144
Spring 3.1 and MVC Testing Support Sam Brannen Swiftmind Rossen Stoyanchev SpringSource, VMware SpringOne 2GX October 28, 2011

Spring 3.1 and MVC Testing Support

Embed Size (px)

DESCRIPTION

This session will give attendees an overview of the new testing features in Spring 3.1 as well the new Spring MVC test support. Sam Brannen will demonstrate how to use the Spring TestContext Framework to write integration tests for Java-based Spring configuration using @Configuration classes. He'll then compare and contrast this approach with XML-based configuration and follow up with a discussion of the new testing support for bean definition profiles. Next, Rossen Stoyanchev will show attendees how testing server-side code with annotated controllers and client-side code with the RestTemplate just got a whole lot easier with the new Spring MVC test support. Come to this session to see these new Spring testing features in action and learn how you can get involved in the Spring MVC Test Support project.

Citation preview

Page 1: Spring 3.1 and MVC Testing Support

Spring 3.1 and MVCTesting Support

Sam BrannenSwiftmind

Rossen StoyanchevSpringSource, VMware

SpringOne 2GXOctober 28, 2011

Page 2: Spring 3.1 and MVC Testing Support

Sam BrannenSenior Software Consultant @ Swiftmind

Java developer with 13+ years' experience

Spring Framework Core Developer

Lead author of Spring in a Nutshell

Previous SpringSource dm Server™ developer

Presenter on Spring, Java, OSGi, and testing

Page 3: Spring 3.1 and MVC Testing Support

Rossen StoyanchevStaff Engineer SpringSource, VMware

Spring MVC, Spring Web Flow committer

Teach and consult, Spring Projects

Spring Web course author

NYC area

Page 4: Spring 3.1 and MVC Testing Support

Goals of thePresentation

Gain an overview of testing featuresin Spring 3.1

Learn about the new Spring MVCTest Support project

Page 5: Spring 3.1 and MVC Testing Support

AgendaSpring TestContext Framework

Testing with @Configuration Classes

Testing with Environment Profiles

Spring MVC Test Support

Q&A

Page 6: Spring 3.1 and MVC Testing Support

Show of Hands...JUnit / TestNG

Spring 2.5 / 3.0 / 3.1

Integration testing with Spring

Spring TestContext Framework

Spring MVC

Spring MVC Test Support

Page 7: Spring 3.1 and MVC Testing Support

Spring TestContextFramework

Page 8: Spring 3.1 and MVC Testing Support

Introduced in Spring 2.5

Page 9: Spring 3.1 and MVC Testing Support

Revised in Spring 3.1

Page 10: Spring 3.1 and MVC Testing Support

Unit and integration testing

Page 11: Spring 3.1 and MVC Testing Support

Annotation-driven

Page 12: Spring 3.1 and MVC Testing Support

Convention over Configuration

Page 13: Spring 3.1 and MVC Testing Support

JUnit & TestNG

Page 14: Spring 3.1 and MVC Testing Support

Spring & Unit TestingPOJO-based programming model

Program to interfaces

IoC / Dependency Injection

Out-of-container testability

Testing mocks/stubs for various APIs: Servlet,Portlet, JNDI

General purpose testing utilitiesReflectionTestUtilsModelAndViewAssert

Page 15: Spring 3.1 and MVC Testing Support

Spring & Integration TestingApplicationContext management & caching

Dependency injection of test instances

Transactional test managementwith default rollback semantics

SimpleJdbcTestUtils

JUnit 3.8 support classes are deprecated as ofSpring 3.0/3.1

Page 16: Spring 3.1 and MVC Testing Support

Spring Test AnnotationsApplication Contexts

@ContextConfiguration, @DirtiesContext

@TestExecutionListeners

Dependency Injection@Autowired, @Qualifier, @Inject, …

Transactions@Transactional, @TransactionConfiguration, @Rollback,@BeforeTransaction, @AfterTransaction

Page 17: Spring 3.1 and MVC Testing Support

Spring JUnit AnnotationsTesting Profiles

groups, not bean definitionprofiles@IfProfileValue,@ProfileValueSourceConfiguration

JUnit extensions@Timed, @Repeat

Page 18: Spring 3.1 and MVC Testing Support

Using the TestContextFramework

Use the SpringJUnit4ClassRunner forJUnit 4.5+

Instrument test class withTestContextManager for TestNG

Extend one of the base classesAbstract(Transactional)[JUnit4|TestNG]SpringContextTests

Page 19: Spring 3.1 and MVC Testing Support

Example: @POJO Test Class

public class OrderServiceTests {

@Test public void testOrderService() { … }}

Page 20: Spring 3.1 and MVC Testing Support

Example: @POJO Test Class@RunWith(SpringJUnit4ClassRunner.class)

public class OrderServiceTests {

@Test public void testOrderService() { … }}

Page 21: Spring 3.1 and MVC Testing Support

Example: @POJO Test Class@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration

public class OrderServiceTests {

@Test public void testOrderService() { … }}

Page 22: Spring 3.1 and MVC Testing Support

Example: @POJO Test Class@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration // defaults to// OrderServiceTests-context.xml in same packagepublic class OrderServiceTests {

@Test public void testOrderService() { … }}

Page 23: Spring 3.1 and MVC Testing Support

Example: @POJO Test Class@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration // defaults to// OrderServiceTests-context.xml in same packagepublic class OrderServiceTests { @Autowired private OrderService orderService;

@Test public void testOrderService() { … }}

Page 24: Spring 3.1 and MVC Testing Support

Example: @POJO Test Class@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration // defaults to// OrderServiceTests-context.xml in same package@Transactionalpublic class OrderServiceTests { @Autowired private OrderService orderService;

@Test public void testOrderService() { … }}

Page 25: Spring 3.1 and MVC Testing Support

Example: @POJO Test Class@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration // defaults to// OrderServiceTests-context.xml in same package@Transactionalpublic class OrderServiceTests { @Autowired private OrderService orderService; @BeforeTransaction public void verifyInitialDatabaseState() { … }

@Test public void testOrderService() { … }}

Page 26: Spring 3.1 and MVC Testing Support

Example: @POJO Test Class@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration // defaults to// OrderServiceTests-context.xml in same package@Transactionalpublic class OrderServiceTests { @Autowired private OrderService orderService; @BeforeTransaction public void verifyInitialDatabaseState() { … } @Before public void setUpTestDataWithinTransaction() { … } @Test public void testOrderService() { … }}

Page 27: Spring 3.1 and MVC Testing Support

Core Components

Page 28: Spring 3.1 and MVC Testing Support

TestContextTracks context for current test

Delegates to a ContextLoader

Caches ApplicationContext

Page 29: Spring 3.1 and MVC Testing Support

TestContextManagerManages the TestContext

Signals events to listeners:before: before-class methodsafter: test instantiationbefore: before methodsafter: after methodsafter: after-class methods

Page 30: Spring 3.1 and MVC Testing Support

TestExecutionListener SPIReacts to test execution events

Receives reference to current TestContext

Out of the box:DependencyInjectionTestExecutionListenerDirtiesContextTestExecutionListenerTransactionalTestExecutionListener

Page 31: Spring 3.1 and MVC Testing Support

TestExecutionListener

Page 32: Spring 3.1 and MVC Testing Support

TEL: Prepare Instance

Page 33: Spring 3.1 and MVC Testing Support

TEL: Befores and Afters

Page 34: Spring 3.1 and MVC Testing Support

ContextLoader SPIStrategy for loading application contexts

from resource locations

Out of the box:GenericXmlContextLoaderGenericPropertiesContextLoader

Page 35: Spring 3.1 and MVC Testing Support

ContextLoader 2.5

Page 36: Spring 3.1 and MVC Testing Support

Putting it all together

Page 37: Spring 3.1 and MVC Testing Support

New in Spring 3.1

Page 38: Spring 3.1 and MVC Testing Support

Support for ...

Page 39: Spring 3.1 and MVC Testing Support

testing with @Configuration classes

Page 40: Spring 3.1 and MVC Testing Support

and

Page 41: Spring 3.1 and MVC Testing Support

testing with environment profiles

Page 42: Spring 3.1 and MVC Testing Support

made possible by ...

Page 43: Spring 3.1 and MVC Testing Support

SmartContextLoader

Page 44: Spring 3.1 and MVC Testing Support

AnnotationConfigContextLoader

Page 45: Spring 3.1 and MVC Testing Support

DelegatingSmartContextLoader

Page 46: Spring 3.1 and MVC Testing Support

updated context cache key generation

Page 47: Spring 3.1 and MVC Testing Support

SmartContextLoader SPISupersedes ContextLoader

Strategy for loading applicationcontexts

From @Configuration classes orresource locations

Supports environment profiles

Page 48: Spring 3.1 and MVC Testing Support

ImplementationsGenericXmlContextLoader

GenericPropertiesContextLoader

AnnotationConfigContextLoader

DelegatingSmartContextLoader

Page 49: Spring 3.1 and MVC Testing Support

ContextLoader 2.5

Page 50: Spring 3.1 and MVC Testing Support

ContextLoader 3.1

Page 51: Spring 3.1 and MVC Testing Support

Testing with@Configuration Classes

Page 52: Spring 3.1 and MVC Testing Support

@ContextConfigurationaccepts a new classes attribute...

Page 53: Spring 3.1 and MVC Testing Support

@ContextConfiguration( classes={DataAccessConfig.class, ServiceConfig.class})

Page 54: Spring 3.1 and MVC Testing Support

First, a review with XML config forcomparison...

Page 55: Spring 3.1 and MVC Testing Support

OrderServiceTest-context.xml

<?xml version="1.0" encoding="UTF-8"?><beans ...> <!-- will be injected into OrderServiceTest --> <bean id="orderService" class="com.example.OrderServiceImpl"> <!-- set properties, etc. --> </bean> <!-- other beans --></beans>

Page 56: Spring 3.1 and MVC Testing Support

OrderServiceTest.java

package com.example;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfigurationpublic class OrderServiceTest { @Autowired private OrderService orderService; @Test public void testOrderService() { // test the orderService }}

Page 57: Spring 3.1 and MVC Testing Support

Let's rework that example to use a@Configuration class and the newAnnotationConfigContextLoader...

Page 58: Spring 3.1 and MVC Testing Support

OrderServiceTest.java

@RunWith(SpringJUnit4ClassRunner.class)

public class OrderServiceTest {

@Autowired private OrderService orderService; // @Test methods ...}

Page 59: Spring 3.1 and MVC Testing Support

OrderServiceTest.java

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration( loader=AnnotationConfigContextLoader.class)public class OrderServiceTest {

@Autowired private OrderService orderService; // @Test methods ...}

Page 60: Spring 3.1 and MVC Testing Support

OrderServiceTest.java

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfigurationpublic class OrderServiceTest {

@Autowired private OrderService orderService; // @Test methods ...}

Page 61: Spring 3.1 and MVC Testing Support

OrderServiceTest.java

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfigurationpublic class OrderServiceTest { @Configuration static class Config {

} @Autowired private OrderService orderService; // @Test methods ...}

Page 62: Spring 3.1 and MVC Testing Support

OrderServiceTest.java

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfigurationpublic class OrderServiceTest { @Configuration static class Config { @Bean // will be injected into OrderServiceTest public OrderService orderService() { OrderService orderService = new OrderServiceImpl(); // set properties, etc. return orderService; } } @Autowired private OrderService orderService; // @Test methods ...}

Page 63: Spring 3.1 and MVC Testing Support

What's changed?No XML

Bean definitions are converted toJava

using @Configuration and @Bean

Otherwise, the test remainsunchanged

Page 64: Spring 3.1 and MVC Testing Support

But what if we don't want a staticinner @Configuration class?

Page 65: Spring 3.1 and MVC Testing Support

Just externalize the config...

Page 66: Spring 3.1 and MVC Testing Support

OrderServiceConfig.java

@Configurationpublic class OrderServiceConfig { @Bean // will be injected into OrderServiceTest public OrderService orderService() { OrderService orderService = new OrderServiceImpl(); // set properties, etc. return orderService; }}

Page 67: Spring 3.1 and MVC Testing Support

And reference the config classes in@ContextConfiguration...

Page 68: Spring 3.1 and MVC Testing Support

OrderServiceConfig.java

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes=OrderServiceConfig.class)public class OrderServiceTest { @Autowired private OrderService orderService; @Test public void testOrderService() { // test the orderService }}

Page 69: Spring 3.1 and MVC Testing Support

@Configuration + XMLQ: How can we combine@Configuration classes with XMLconfig?

A: Choose one as the entry point.

That's how it works in productionanyway

Page 70: Spring 3.1 and MVC Testing Support

Importing ConfigurationIn XML:

include @Configuration classes viacomponent scanningor define them as normal Springbeans

In an @Configuration class:use @ImportResource to import XMLconfig files

Page 71: Spring 3.1 and MVC Testing Support

Testing withEnvironment Profiles

Page 72: Spring 3.1 and MVC Testing Support

@ActiveProfilesTo activate bean definition profiles in tests...

Annotate a test class with@ActiveProfiles

Supply a list of profiles to beactivated for the test

Can be used with @Configurationclasses and XML config

Page 73: Spring 3.1 and MVC Testing Support

Let's look at an example with XMLconfig...

Page 74: Spring 3.1 and MVC Testing Support

app-config.xml (1/2)

<beans ... > <bean id="transferService" class="com.example.DefaultTransferService"> <constructor-arg ref="accountRepository"/> <constructor-arg ref="feePolicy"/> </bean> <bean id="accountRepository" class="com.example.JdbcAccountRepository"> <constructor-arg ref="dataSource"/> </bean> <bean id="feePolicy" class="com.example.ZeroFeePolicy"/> <!-- dataSource --></beans>

Page 75: Spring 3.1 and MVC Testing Support

app-config.xml (2/2)

<beans ... > <!-- transferService, accountRepository, feePolicy -->

</beans>

Page 76: Spring 3.1 and MVC Testing Support

app-config.xml (2/2)

<beans ... > <!-- transferService, accountRepository, feePolicy --> <beans profile="production"> <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"/> </beans>

</beans>

Page 77: Spring 3.1 and MVC Testing Support

app-config.xml (2/2)

<beans ... > <!-- transferService, accountRepository, feePolicy --> <beans profile="production"> <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"/> </beans> <beans profile="dev"> <jdbc:embedded-database id="dataSource"> <jdbc:script location="classpath:schema.sql"/> <jdbc:script location="classpath:test-data.sql"/> </jdbc:embedded-database> </beans></beans>

Page 78: Spring 3.1 and MVC Testing Support

TransferServiceTest.java

@RunWith(SpringJUnit4ClassRunner.class)

public class TransferServiceTest { @Autowired private TransferService transferService; @Test public void testTransferService() { // test the transferService }}

Page 79: Spring 3.1 and MVC Testing Support

TransferServiceTest.java

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("/app-config.xml")public class TransferServiceTest { @Autowired private TransferService transferService; @Test public void testTransferService() { // test the transferService }}

Page 80: Spring 3.1 and MVC Testing Support

TransferServiceTest.java

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("/app-config.xml")@ActiveProfiles("dev")public class TransferServiceTest { @Autowired private TransferService transferService; @Test public void testTransferService() { // test the transferService }}

Page 81: Spring 3.1 and MVC Testing Support

And now an example with@Configuration classes

Page 82: Spring 3.1 and MVC Testing Support

TransferServiceConfig.java

@Configurationpublic class TransferServiceConfig { @Autowired DataSource dataSource; @Bean public TransferService transferService() { return new DefaultTransferService(accountRepository(), feePolicy()); } @Bean public AccountRepository accountRepository() { return new JdbcAccountRepository(dataSource); } @Bean public FeePolicy feePolicy() { return new ZeroFeePolicy(); }}

Page 83: Spring 3.1 and MVC Testing Support

}

JndiDataConfig.java

@Configuration@Profile("production")public class JndiDataConfig { @Bean public DataSource dataSource() throws Exception { Context ctx = new InitialContext(); return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource"); }}

Page 84: Spring 3.1 and MVC Testing Support

StandaloneDataConfig.java

@Configuration@Profile("dev")public class StandaloneDataConfig { @Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.HSQL) .addScript("classpath:schema.sql") .addScript("classpath:test-data.sql") .build(); }}

Page 85: Spring 3.1 and MVC Testing Support

And finally the test class...

Page 86: Spring 3.1 and MVC Testing Support

TransferServiceTest.java

package com.bank.service;@RunWith(SpringJUnit4ClassRunner.class)

public class TransferServiceTest { @Autowired private TransferService transferService; @Test public void testTransferService() { // test the transferService }}

Page 87: Spring 3.1 and MVC Testing Support

TransferServiceTest.java

package com.bank.service;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration( classes={ TransferServiceConfig.class, StandaloneDataConfig.class, JndiDataConfig.class})public class TransferServiceTest { @Autowired private TransferService transferService; @Test public void testTransferService() { // test the transferService }}

Page 88: Spring 3.1 and MVC Testing Support

TransferServiceTest.java

package com.bank.service;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration( classes={ TransferServiceConfig.class, StandaloneDataConfig.class, JndiDataConfig.class})@ActiveProfiles("dev")public class TransferServiceTest { @Autowired private TransferService transferService; @Test public void testTransferService() { // test the transferService }}

Page 89: Spring 3.1 and MVC Testing Support

Active Profile Inheritance@ActiveProfiles supports inheritance as well

Via the inheritProfiles attribute

See Javadoc for an example

Page 90: Spring 3.1 and MVC Testing Support

ApplicationContextCaching

Page 91: Spring 3.1 and MVC Testing Support

Until Spring 3.1

Page 92: Spring 3.1 and MVC Testing Support

application contexts were cached

Page 93: Spring 3.1 and MVC Testing Support

but using only resource locations forthe key.

Page 94: Spring 3.1 and MVC Testing Support

Now there are differentrequirements...

Page 95: Spring 3.1 and MVC Testing Support

New Key Generation AlgorithmThe context cache key generation algorithm has been updated to include...

locations (from @ContextConfiguration)

classes (from @ContextConfiguration)

contextLoader (from @ContextConfiguration)

activeProfiles (from @ActiveProfiles)

Page 96: Spring 3.1 and MVC Testing Support

SummaryThe Spring TestContext Framework simplifiesintegration testing of Spring-basedapplications

Spring 3.1 provides first-class testing supportfor:

@Configuration classesEnvironment profiles

See the Testing with @Configuration Classesand Profiles blog for further insight

Page 97: Spring 3.1 and MVC Testing Support

Spring MVC TestSupport

Page 98: Spring 3.1 and MVC Testing Support

How Do You Test an@Controller?

Page 99: Spring 3.1 and MVC Testing Support

@Controller@RequestMapping("/accounts")public class AccountController { // ... @ModelAttribute public Account getAccount(String number) { return this.accountManager.getAccount(number); } @RequestMapping(method = RequestMethod.POST) public String save(@Valid Account account, BindingResult result) { if (result.hasErrors()) { return "accounts/edit"; } this.accountManager.saveOrUpdate(account); return "redirect:accounts"; }}

Page 100: Spring 3.1 and MVC Testing Support

Unit Test?Create controller instance

Mock or stub services & repositories

Page 101: Spring 3.1 and MVC Testing Support

Example@Testpublic void testSave() { Account account = new Account(); BindingResult result = new BeanPropertyBindingResult(account, "account");

}

Page 102: Spring 3.1 and MVC Testing Support

Example@Testpublic void testSave() { Account account = new Account(); BindingResult result = new BeanPropertyBindingResult(account, "account"); AccountManager mgr = createMock(AccountManager.class); mgr.saveOrUpdate(account); replay(mgr);

}

Page 103: Spring 3.1 and MVC Testing Support

Example@Testpublic void testSave() { Account account = new Account(); BindingResult result = new BeanPropertyBindingResult(account, "account"); AccountManager mgr = createMock(AccountManager.class); mgr.saveOrUpdate(account); replay(mgr); AccountController contrlr = new AccountController(mgr); String view = contrlr.save(account, result);

}

Page 104: Spring 3.1 and MVC Testing Support

Example@Testpublic void testSave() { Account account = new Account(); BindingResult result = new BeanPropertyBindingResult(account, "account"); AccountManager mgr = createMock(AccountManager.class); mgr.saveOrUpdate(account); replay(mgr); AccountController contrlr = new AccountController(mgr); String view = contrlr.save(account, result); assertEquals("redirect:accounts", view); verify(mgr);}

Page 105: Spring 3.1 and MVC Testing Support

Example With Failure@Testpublic void testSave() { Account account = new Account(); BindingResult result = new BeanPropertyBindingResult(account, "account"); result.reject("error.code", "default message")

}

Page 106: Spring 3.1 and MVC Testing Support

Example With Failure@Testpublic void testSave() { Account account = new Account(); BindingResult result = new BeanPropertyBindingResult(account, "account"); result.reject("error.code", "default message") AccountManager mgr = createMock(AccountManager.class); replay(mgr);

}

Page 107: Spring 3.1 and MVC Testing Support

Example With Failure@Testpublic void testSave() { Account account = new Account(); BindingResult result = new BeanPropertyBindingResult(account, "account"); result.reject("error.code", "default message") AccountManager mgr = createMock(AccountManager.class); replay(mgr); AccountController contrlr = new AccountController(mgr); String view = contrlr.save(account, result); assertEquals("accounts/edit", view); verify(mgr);}

Page 108: Spring 3.1 and MVC Testing Support

Not Fully TestedRequest mappings

Binding errors

Type conversion

Etc.

Page 109: Spring 3.1 and MVC Testing Support

Integration Test?Selenium

JWebUnit

etc.

Page 110: Spring 3.1 and MVC Testing Support

It Requires...A running servlet container

More time to execute

More effort to maintain

Server is a black box

Page 111: Spring 3.1 and MVC Testing Support

Actually...

Page 112: Spring 3.1 and MVC Testing Support

it's an end-to-end test

Page 113: Spring 3.1 and MVC Testing Support

the only way to verify...Client-side behavior

Interaction with other server instances

Redis, Rabbit, etc.

Page 114: Spring 3.1 and MVC Testing Support

We'd also like to...Test controllers once!

Fully & quickly

Execute tests often

Page 115: Spring 3.1 and MVC Testing Support

In summary...We can't replace the need for end-to-

end tests

But we can minimize errors

Have confidence in @MVC code

During end-to-end tests

Page 116: Spring 3.1 and MVC Testing Support

Spring MVC TestBuilt on spring-test

No Servlet container

Drives Spring MVC infrastructure

Both server & client-side test support (i.e. RestTemplate code)

Inspired by spring-ws-test

Page 117: Spring 3.1 and MVC Testing Support

The ApproachRe-use controller test fixtures

I.e. mocked services & repositories

Invoke @Controller classes through@MVC infrastructure

Page 118: Spring 3.1 and MVC Testing Support

ExampleString contextLoc = "classpath:appContext.xml";String warDir = "src/main/webapp";MockMvc mockMvc = xmlConfigSetup(contextLoc) .configureWebAppRootDir(warDir, false) .build();mockMvc.perform(post("/persons")) .andExpect(response().status().isOk()) .andExpect(response().forwardedUrl("/add.jsp")) .andExpect(model().size(1)) .andExpect(model().hasAttributes("person"));

Page 119: Spring 3.1 and MVC Testing Support

Under the CoversMock request/response from spring-test

DispatcherServlet replacement

Multiple ways to initialize MVCinfrastructure

Save results for expectations

Page 120: Spring 3.1 and MVC Testing Support

Ways To Initialize MVCInfrastructure

Page 121: Spring 3.1 and MVC Testing Support

From Existing XML Config// XML configMockMvc mockMvc = xmlConfigSetup("classpath:appContext.xml") .activateProfiles(..) .configureWebAppRootDir(warDir, false) .build();

Page 122: Spring 3.1 and MVC Testing Support

From Existing Java Config// Java configMockMvc mockMvc = annotationConfigSetup(WebConfig.class) .activateProfiles(..) .configureWebAppRootDir(warDir, false) .build();

Page 123: Spring 3.1 and MVC Testing Support

Manually MockMvc mockMvc = standaloneSetup(new PersonController()) .setMessageConverters(..) .setValidator(..) .setConversionService(..) .addInterceptors(..) .setViewResolvers(..) .setLocaleResolver(..) .build();

Page 124: Spring 3.1 and MVC Testing Support

About Manual SetupMVC components instantiated directly

Not looked up in Spring context

Focused, readable tests

But must verify MVC config separately

Page 125: Spring 3.1 and MVC Testing Support

TestContext Framework Example@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration( locations={"/org/example/servlet-context.xml"})public class TestContextTests { @Autowired private WebApplicationContext wac; @Before public void setup() { MockMvc mockMvc = MockMvcBuilders.webApplicationContextSetup(this.wac) .build(); }}

Page 126: Spring 3.1 and MVC Testing Support

TestContext FrameworkCaches loaded Spring configuration

Potentially across all tests!

Page 127: Spring 3.1 and MVC Testing Support

However...WebApplicationContext not supported yet

To be supported in Spring 3.2

Page 129: Spring 3.1 and MVC Testing Support

Step 1Add static imports

MockMvcBuilders.*

MockMvcRequestBuilders.*

MockMvcResultActions.*

Page 130: Spring 3.1 and MVC Testing Support

Easy to remember...MockMvc*

Page 131: Spring 3.1 and MVC Testing Support

Also in Eclipse...Add MockMvc* classes in Preferences

Java -> Editor -> Favorites

Helps content assist

Page 132: Spring 3.1 and MVC Testing Support

Step 2Initialize MVC infrastructure

String contextLoc = "classpath:appContext.xml";String warDir = "src/main/webapp";MockMvc mockMvc = xmlConfigSetup("classpath:appContext.xml") .configureWebAppRootDir(warDir, false) .build()

// ...

Page 133: Spring 3.1 and MVC Testing Support

Step 3Build Request

String contextLoc = "classpath:appContext.xml";String warDir = "src/main/webapp";MockMvc mockMvc = xmlConfigSetup("classpath:appContext.xml") .configureWebAppRootDir(warDir, false) .build()mockMvc.perform(get("/").accept(MediaType.APPLICATION_XML))

// ...

Page 134: Spring 3.1 and MVC Testing Support

Step 4Add Expectations

String contextLoc = "classpath:appContext.xml";String warDir = "src/main/webapp";MockMvc mockMvc = xmlConfigSetup("classpath:appContext.xml") .configureWebAppRootDir(warDir, false) .build()mockMvc.perform(get("/").accept(MediaType.APPLICATION_XML)) .andExpect(response().status().isOk()) .andExpect(response().contentType(MediaType)) .andExpect(response().content().xpath(String).exists()) .andExpect(response().redirectedUrl(String)) .andExpect(model().hasAttributes(String...));

// ...

Page 135: Spring 3.1 and MVC Testing Support

Step 5Debug

String contextLoc = "classpath:appContext.xml";String warDir = "src/main/webapp";MockMvc mockMvc = xmlConfigSetup("classpath:appContext.xml") .configureWebAppRootDir(warDir, false) .build()mockMvc.perform(get("/").accept(MediaType.APPLICATION_XML)) .andPrint(toConsole());

// ...

Page 136: Spring 3.1 and MVC Testing Support

Demo

https://github.com/SpringSource/spring-test-mvc

Sample Tests:

org.springframework.test.web.server.samples

Page 137: Spring 3.1 and MVC Testing Support

Client-Side ExampleRestTemplate restTemplate = ... ;MockRestServiceServer.createServer(restTemplate) .expect(requestTo(String)) .andExpect(method(HttpMethod)) .andExpect(body(String)) .andExpect(headerContains(String, String)) .andRespond(withResponse(String, HttpHeaders));

Page 138: Spring 3.1 and MVC Testing Support

Project Availabilitygithub.com/SpringSource/spring-test-mvc

Request for feedback!

Send comments

Pull requests

Page 139: Spring 3.1 and MVC Testing Support

Nightly Snapshot Available<repository> <id>org.springframework.maven.snapshot</id> <name>Spring Maven Snapshot Repository</name> <url>http://maven.springframework.org/snapshot</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots></repository>

Page 140: Spring 3.1 and MVC Testing Support

In Closing ...

Page 141: Spring 3.1 and MVC Testing Support

This PresentationSource:https://github.com/rstoyanchev/spring-31-and-mvc-testing-support

Slides:http://rstoyanchev.github.com/spring-31-and-mvc-test

Page 142: Spring 3.1 and MVC Testing Support

Resources for Spring MVC TestProject Home:https://github.com/SpringSource/spring-test-mvc

Sample Tests:org.springframework.test.web.server.samples

Page 143: Spring 3.1 and MVC Testing Support

Resources for Core SpringSpring Framework:http://www.springsource.org/spring-core

Reference Manual: Spring 3.1 RC1

Forums: http://forum.springframework.org

JIRA: https://jira.springsource.org

Spring in a Nutshell … available in 2012

Page 144: Spring 3.1 and MVC Testing Support

Q&A

Sam BrannenWeb: Swiftmind.com

Twitter: @sam_brannen

Rossen StoyanchevWeb: SpringSource.com

Twitter: @rstoya05