Transcript
Page 1: Spring 3.1 and MVC Testing Support - 4Developers

Spring 3.1 and MVCTesting Support

Sam BrannenSwiftmind

4Developers18 April 2012

Page 2: Spring 3.1 and MVC Testing Support - 4Developers

Sam BrannenSpring & Java Consultant @ Swiftmind

Developing Java for over 14 years

Spring Framework Core Committer

Spring Trainer

Lead author of “Spring in a Nutshell”

Twitter: @sam_brannen

Page 3: Spring 3.1 and MVC Testing Support - 4Developers

Goals of thePresentation

Gain an overview of testing featuresin Spring 3.1

Learn about the new Spring MVCTest Support project

Page 4: Spring 3.1 and MVC Testing Support - 4Developers

AgendaSpring TestContext Framework

Testing with @Configuration Classes

Testing with Environment Profiles

Spring MVC Test Support

Q&A

Page 5: Spring 3.1 and MVC Testing Support - 4Developers

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 6: Spring 3.1 and MVC Testing Support - 4Developers

Spring TestContextFramework

Page 7: Spring 3.1 and MVC Testing Support - 4Developers

Introduced in Spring 2.5

Page 8: Spring 3.1 and MVC Testing Support - 4Developers

Revised in Spring 3.1

Page 9: Spring 3.1 and MVC Testing Support - 4Developers

Unit and integration testing

Page 10: Spring 3.1 and MVC Testing Support - 4Developers

Annotation-driven

Page 11: Spring 3.1 and MVC Testing Support - 4Developers

Convention over Configuration

Page 12: Spring 3.1 and MVC Testing Support - 4Developers

JUnit & TestNG

Page 13: Spring 3.1 and MVC Testing Support - 4Developers

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 14: Spring 3.1 and MVC Testing Support - 4Developers

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 15: Spring 3.1 and MVC Testing Support - 4Developers

Spring Test AnnotationsApplication Contexts

@ContextConfiguration, @DirtiesContext

@TestExecutionListeners

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

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

Page 16: Spring 3.1 and MVC Testing Support - 4Developers

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 17: Spring 3.1 and MVC Testing Support - 4Developers

Example: @POJO Test Class

public class OrderServiceTests {

@Test public void testOrderService() { … }}

Page 18: Spring 3.1 and MVC Testing Support - 4Developers

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

public class OrderServiceTests {

@Test public void testOrderService() { … }}

Page 19: Spring 3.1 and MVC Testing Support - 4Developers

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

public class OrderServiceTests {

@Test public void testOrderService() { … }}

Page 20: Spring 3.1 and MVC Testing Support - 4Developers

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

@Test public void testOrderService() { … }}

Page 21: Spring 3.1 and MVC Testing Support - 4Developers

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 22: Spring 3.1 and MVC Testing Support - 4Developers

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 23: Spring 3.1 and MVC Testing Support - 4Developers

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 24: Spring 3.1 and MVC Testing Support - 4Developers

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 25: Spring 3.1 and MVC Testing Support - 4Developers

Core Components

Page 26: Spring 3.1 and MVC Testing Support - 4Developers

TestContextTracks context for current test

Delegates to a ContextLoader

Caches ApplicationContext

Page 27: Spring 3.1 and MVC Testing Support - 4Developers

TestContextManagerManages the TestContext

Signals events to listeners...

Page 28: Spring 3.1 and MVC Testing Support - 4Developers

TestExecutionListener SPIReacts to test execution events

Receives reference to current TestContext

Out of the box:DependencyInjectionTestExecutionListenerDirtiesContextTestExecutionListenerTransactionalTestExecutionListener

Page 29: Spring 3.1 and MVC Testing Support - 4Developers

ContextLoader SPIStrategy for loading application contexts

from resource locations

Page 30: Spring 3.1 and MVC Testing Support - 4Developers

Putting it all together

Page 31: Spring 3.1 and MVC Testing Support - 4Developers

New in Spring 3.1

Page 32: Spring 3.1 and MVC Testing Support - 4Developers

Support for ...

Page 33: Spring 3.1 and MVC Testing Support - 4Developers

testing with @Configuration classes

Page 34: Spring 3.1 and MVC Testing Support - 4Developers

and

Page 35: Spring 3.1 and MVC Testing Support - 4Developers

testing with environment profiles

Page 36: Spring 3.1 and MVC Testing Support - 4Developers

made possible by ...

Page 37: Spring 3.1 and MVC Testing Support - 4Developers

SmartContextLoader

Page 38: Spring 3.1 and MVC Testing Support - 4Developers

AnnotationConfigContextLoader

Page 39: Spring 3.1 and MVC Testing Support - 4Developers

DelegatingSmartContextLoader

Page 40: Spring 3.1 and MVC Testing Support - 4Developers

updated context cache key generation

Page 41: Spring 3.1 and MVC Testing Support - 4Developers

SmartContextLoader SPISupersedes ContextLoader

Strategy for loading applicationcontexts

From @Configuration classes orresource locations

Supports environment profiles

Page 42: Spring 3.1 and MVC Testing Support - 4Developers

ImplementationsGenericXmlContextLoader

GenericPropertiesContextLoader

AnnotationConfigContextLoader

DelegatingSmartContextLoader

Page 43: Spring 3.1 and MVC Testing Support - 4Developers

ContextLoader 3.1

Page 44: Spring 3.1 and MVC Testing Support - 4Developers

Testing with@Configuration Classes

Page 45: Spring 3.1 and MVC Testing Support - 4Developers

@ContextConfigurationaccepts a new classes attribute...

Page 46: Spring 3.1 and MVC Testing Support - 4Developers

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

Page 47: Spring 3.1 and MVC Testing Support - 4Developers

First, a review with XML config forcomparison...

Page 48: Spring 3.1 and MVC Testing Support - 4Developers

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 49: Spring 3.1 and MVC Testing Support - 4Developers

OrderServiceTest.java

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

Page 50: Spring 3.1 and MVC Testing Support - 4Developers

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

Page 51: Spring 3.1 and MVC Testing Support - 4Developers

OrderServiceTest.java

@RunWith(SpringJUnit4ClassRunner.class)

public class OrderServiceTest {

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

Page 52: Spring 3.1 and MVC Testing Support - 4Developers

OrderServiceTest.java

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

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

Page 53: Spring 3.1 and MVC Testing Support - 4Developers

OrderServiceTest.java

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

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

Page 54: Spring 3.1 and MVC Testing Support - 4Developers

OrderServiceTest.java

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

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

Page 55: Spring 3.1 and MVC Testing Support - 4Developers

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 56: Spring 3.1 and MVC Testing Support - 4Developers

What's changed?No XML

Bean definitions are converted toJava

using @Configuration and @Bean

Otherwise, the test remainsunchanged

Page 57: Spring 3.1 and MVC Testing Support - 4Developers

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

Page 58: Spring 3.1 and MVC Testing Support - 4Developers

Just externalize the config...

Page 59: Spring 3.1 and MVC Testing Support - 4Developers

OrderServiceConfig.java

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

Page 60: Spring 3.1 and MVC Testing Support - 4Developers

And reference the config classes in@ContextConfiguration...

Page 61: Spring 3.1 and MVC Testing Support - 4Developers

OrderServiceConfig.java

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

Page 62: Spring 3.1 and MVC Testing Support - 4Developers

@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 63: Spring 3.1 and MVC Testing Support - 4Developers

Importing ConfigurationIn XML:

include @Configuration classes viacomponent scanningor define them as normal Springbeans

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

Page 64: Spring 3.1 and MVC Testing Support - 4Developers

Testing withEnvironment Profiles

Page 65: Spring 3.1 and MVC Testing Support - 4Developers

@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 66: Spring 3.1 and MVC Testing Support - 4Developers

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

Page 67: Spring 3.1 and MVC Testing Support - 4Developers

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 68: Spring 3.1 and MVC Testing Support - 4Developers

app-config.xml (2/2)

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

</beans>

Page 69: Spring 3.1 and MVC Testing Support - 4Developers

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 70: Spring 3.1 and MVC Testing Support - 4Developers

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 71: Spring 3.1 and MVC Testing Support - 4Developers

TransferServiceTest.java

@RunWith(SpringJUnit4ClassRunner.class)

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

Page 72: Spring 3.1 and MVC Testing Support - 4Developers

TransferServiceTest.java

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

Page 73: Spring 3.1 and MVC Testing Support - 4Developers

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 74: Spring 3.1 and MVC Testing Support - 4Developers

And now an example with@Configuration classes

Page 75: Spring 3.1 and MVC Testing Support - 4Developers

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 76: Spring 3.1 and MVC Testing Support - 4Developers

}

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 77: Spring 3.1 and MVC Testing Support - 4Developers

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 78: Spring 3.1 and MVC Testing Support - 4Developers

And finally the test class...

Page 79: Spring 3.1 and MVC Testing Support - 4Developers

TransferServiceTest.java

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

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

Page 80: Spring 3.1 and MVC Testing Support - 4Developers

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 81: Spring 3.1 and MVC Testing Support - 4Developers

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 82: Spring 3.1 and MVC Testing Support - 4Developers

Active Profile Inheritance@ActiveProfiles supports inheritance as well

Via the inheritProfiles attribute

See Javadoc for an example

Page 83: Spring 3.1 and MVC Testing Support - 4Developers

ApplicationContextCaching

Page 84: Spring 3.1 and MVC Testing Support - 4Developers

Until Spring 3.1

Page 85: Spring 3.1 and MVC Testing Support - 4Developers

application contexts were cached

Page 86: Spring 3.1 and MVC Testing Support - 4Developers

but using only resource locations forthe key.

Page 87: Spring 3.1 and MVC Testing Support - 4Developers

Now there are differentrequirements...

Page 88: Spring 3.1 and MVC Testing Support - 4Developers

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 89: Spring 3.1 and MVC Testing Support - 4Developers

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 90: Spring 3.1 and MVC Testing Support - 4Developers

Spring MVC TestSupport

Page 91: Spring 3.1 and MVC Testing Support - 4Developers

How Do You Test an@Controller?

Page 92: Spring 3.1 and MVC Testing Support - 4Developers

@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 93: Spring 3.1 and MVC Testing Support - 4Developers

Unit Test?Create controller instance

Mock or stub services & repositories

Page 94: Spring 3.1 and MVC Testing Support - 4Developers

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

}

Page 95: Spring 3.1 and MVC Testing Support - 4Developers

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 96: Spring 3.1 and MVC Testing Support - 4Developers

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 97: Spring 3.1 and MVC Testing Support - 4Developers

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 98: Spring 3.1 and MVC Testing Support - 4Developers

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

}

Page 99: Spring 3.1 and MVC Testing Support - 4Developers

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 100: Spring 3.1 and MVC Testing Support - 4Developers

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 101: Spring 3.1 and MVC Testing Support - 4Developers

Not Fully TestedRequest mappings?

Binding errors?

Type conversion?

etc.

Page 102: Spring 3.1 and MVC Testing Support - 4Developers

Integration Test?Selenium

JWebUnit

etc.

Page 103: Spring 3.1 and MVC Testing Support - 4Developers

But that requires...A running servlet container

More time to execute

More effort to maintain

Server is a black box

Page 104: Spring 3.1 and MVC Testing Support - 4Developers

And actually...

Page 105: Spring 3.1 and MVC Testing Support - 4Developers

it's an end-to-end test

Page 106: Spring 3.1 and MVC Testing Support - 4Developers

and the only way toverify...

Client-side behavior

Interaction with other server instances

Redis, Rabbit, etc.

Page 107: Spring 3.1 and MVC Testing Support - 4Developers

Ideally we'd like to...Test controllers once!

Fully & quickly

Execute tests often

Page 108: Spring 3.1 and MVC Testing Support - 4Developers

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

end tests.

But we can minimize errors

and gain confidence in @MVC code

during end-to-end tests

Page 109: Spring 3.1 and MVC Testing Support - 4Developers

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 110: Spring 3.1 and MVC Testing Support - 4Developers

The ApproachRe-use controller test fixtures

i.e. mocked services & repositories

Invoke @Controller classes through@MVC infrastructure

Page 111: Spring 3.1 and MVC Testing Support - 4Developers

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 112: Spring 3.1 and MVC Testing Support - 4Developers

Under the CoversMock request/response from spring-test

DispatcherServlet replacement

Multiple ways to initialize MVCinfrastructure

Save results for expectations

Page 113: Spring 3.1 and MVC Testing Support - 4Developers

Ways to Initialize MVCInfrastructure

Page 114: Spring 3.1 and MVC Testing Support - 4Developers

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

Page 115: Spring 3.1 and MVC Testing Support - 4Developers

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

Page 116: Spring 3.1 and MVC Testing Support - 4Developers

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

Page 117: Spring 3.1 and MVC Testing Support - 4Developers

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

Page 118: Spring 3.1 and MVC Testing Support - 4Developers

TestContext FrameworkCaches loaded Spring configuration

Potentially across all tests!

Page 119: Spring 3.1 and MVC Testing Support - 4Developers

However...WebApplicationContext is not yet

supported

To be supported in Spring 3.2

Page 120: Spring 3.1 and MVC Testing Support - 4Developers

How to Use Spring MVCTest

Page 121: Spring 3.1 and MVC Testing Support - 4Developers

Step 1Add static imports

MockMvcBuilders.*

MockMvcRequestBuilders.*

MockMvcResultActions.*

Page 122: Spring 3.1 and MVC Testing Support - 4Developers

Easy to remember...MockMvc*

Page 123: Spring 3.1 and MVC Testing Support - 4Developers

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 124: Spring 3.1 and MVC Testing Support - 4Developers

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 125: Spring 3.1 and MVC Testing Support - 4Developers

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 126: Spring 3.1 and MVC Testing Support - 4Developers

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 127: Spring 3.1 and MVC Testing Support - 4Developers

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 128: Spring 3.1 and MVC Testing Support - 4Developers

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

Request for feedback!

Send comments

Pull requests

Page 129: Spring 3.1 and MVC Testing Support - 4Developers

In Closing ...

Page 130: Spring 3.1 and MVC Testing Support - 4Developers

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

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

Page 131: Spring 3.1 and MVC Testing Support - 4Developers

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

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

Page 132: Spring 3.1 and MVC Testing Support - 4Developers

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

Reference Manual: Spring 3.1.x

Forums: http://forum.springframework.org

JIRA: https://jira.springsource.org

Spring in a Nutshell … available in 2012

Page 133: Spring 3.1 and MVC Testing Support - 4Developers

Q&A

Sam BrannenWeb: Swiftmind.com

Twitter: @sam_brannenSlideshare: sbrannen