@ContextConfiguration
accepts a new classes
attribute...
z, ? | toggle help (this) |
space, → | next slide |
shift-space, ← | previous slide |
d | toggle debug mode |
## <ret> | go to slide # |
c, t | table of contents (vi) |
f | toggle footer |
r | reload slides |
n | toggle notes |
p | run preshow |
ReflectionTestUtils
ModelAndViewAssert
ApplicationContext
management & cachingSimpleJdbcTestUtils
@ContextConfiguration
, @DirtiesContext
@TestExecutionListeners
@Autowired
, @Qualifier
, @Inject
, …@Transactional
, @TransactionConfiguration
, @Rollback
, @BeforeTransaction
, @AfterTransaction
@IfProfileValue
, @ProfileValueSourceConfiguration
@Timed
, @Repeat
SpringJUnit4ClassRunner
for JUnit 4.5+TestContextManager
for TestNGAbstract(Transactional)[JUnit4|TestNG]SpringContextTests
public class OrderServiceTests {
@Test
public void testOrderService() { … }
}
@RunWith(SpringJUnit4ClassRunner.class)
public class OrderServiceTests {
@Test
public void testOrderService() { … }
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class OrderServiceTests {
@Test
public void testOrderService() { … }
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration // defaults to
// OrderServiceTests-context.xml in same package
public class OrderServiceTests {
@Test
public void testOrderService() { … }
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration // defaults to
// OrderServiceTests-context.xml in same package
public class OrderServiceTests {
@Autowired
private OrderService orderService;
@Test
public void testOrderService() { … }
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration // defaults to
// OrderServiceTests-context.xml in same package
@Transactional
public class OrderServiceTests {
@Autowired
private OrderService orderService;
@Test
public void testOrderService() { … }
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration // defaults to
// OrderServiceTests-context.xml in same package
@Transactional
public class OrderServiceTests {
@Autowired
private OrderService orderService;
@BeforeTransaction
public void verifyInitialDatabaseState() { … }
@Test
public void testOrderService() { … }
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration // defaults to
// OrderServiceTests-context.xml in same package
@Transactional
public class OrderServiceTests {
@Autowired
private OrderService orderService;
@BeforeTransaction
public void verifyInitialDatabaseState() { … }
@Before
public void setUpTestDataWithinTransaction() { … }
@Test
public void testOrderService() { … }
}
TestContext
ContextLoader
ApplicationContext
TestContextManager
TestContext
TestExecutionListener
SPITestContext
DependencyInjectionTestExecutionListener
DirtiesContextTestExecutionListener
TransactionalTestExecutionListener
TestExecutionListener
ContextLoader
SPIGenericXmlContextLoader
GenericPropertiesContextLoader
ContextLoader
2.5@Configuration
classesSmartContextLoader
AnnotationConfigContextLoader
DelegatingSmartContextLoader
SmartContextLoader
SPIContextLoader
@Configuration
classes or resource locationsGenericXmlContextLoader
GenericPropertiesContextLoader
AnnotationConfigContextLoader
DelegatingSmartContextLoader
ContextLoader
2.5ContextLoader
3.1@ContextConfiguration
accepts a new classes
attribute...
@ContextConfiguration(
classes={DataAccessConfig.class,
ServiceConfig.class})
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>
OrderServiceTest.java
package com.example;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class OrderServiceTest {
@Autowired
private OrderService orderService;
@Test
public void testOrderService() {
// test the orderService
}
}
@Configuration
class and the new AnnotationConfigContextLoader
...OrderServiceTest.java
@RunWith(SpringJUnit4ClassRunner.class)
public class OrderServiceTest {
@Autowired
private OrderService orderService;
// @Test methods ...
}
OrderServiceTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
loader=AnnotationConfigContextLoader.class)
public class OrderServiceTest {
@Autowired
private OrderService orderService;
// @Test methods ...
}
OrderServiceTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class OrderServiceTest {
@Autowired
private OrderService orderService;
// @Test methods ...
}
OrderServiceTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class OrderServiceTest {
@Configuration
static class Config {
}
@Autowired
private OrderService orderService;
// @Test methods ...
}
OrderServiceTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public 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 ...
}
@Configuration
and @Bean
@Configuration
class?OrderServiceConfig.java
@Configuration
public class OrderServiceConfig {
@Bean // will be injected into OrderServiceTest
public OrderService orderService() {
OrderService orderService = new OrderServiceImpl();
// set properties, etc.
return orderService;
}
}
@ContextConfiguration
...OrderServiceConfig.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=OrderServiceConfig.class)
public class OrderServiceTest {
@Autowired
private OrderService orderService;
@Test
public void testOrderService() {
// test the orderService
}
}
@Configuration
classes with XML config?@Configuration
classes via component scanning@Configuration
class:
@ImportResource
to import XML config filesTo activate bean definition profiles in tests...
@ActiveProfiles
@Configuration
classes and XML configapp-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>
app-config.xml
(2/2)<beans ... >
<!-- transferService, accountRepository, feePolicy -->
</beans>
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>
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>
TransferServiceTest.java
@RunWith(SpringJUnit4ClassRunner.class)
public class TransferServiceTest {
@Autowired
private TransferService transferService;
@Test
public void testTransferService() {
// test the transferService
}
}
TransferServiceTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/app-config.xml")
public class TransferServiceTest {
@Autowired
private TransferService transferService;
@Test
public void testTransferService() {
// test the transferService
}
}
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
}
}
@Configuration
classesTransferServiceConfig.java
@Configuration
public 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();
}
}
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");
}
}
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();
}
}
TransferServiceTest.java
package com.bank.service;
@RunWith(SpringJUnit4ClassRunner.class)
public class TransferServiceTest {
@Autowired
private TransferService transferService;
@Test
public void testTransferService() {
// test the transferService
}
}
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
}
}
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
}
}
@ActiveProfiles
supports inheritance as wellinheritProfiles
attributeThe context cache key generation algorithm has been updated to include...
@ContextConfiguration
)@ContextConfiguration
)@ContextConfiguration
)@ActiveProfiles
)@Configuration
classes@Controller
?
@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";
}
}
@Test
public void testSave() {
Account account = new Account();
BindingResult result =
new BeanPropertyBindingResult(account, "account");
}
@Test
public void testSave() {
Account account = new Account();
BindingResult result =
new BeanPropertyBindingResult(account, "account");
AccountManager mgr = createMock(AccountManager.class);
mgr.saveOrUpdate(account);
replay(mgr);
}
@Test
public 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);
}
@Test
public 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);
}
@Test
public void testSave() {
Account account = new Account();
BindingResult result =
new BeanPropertyBindingResult(account, "account");
result.reject("error.code", "default message")
}
@Test
public 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);
}
@Test
public 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);
}
spring-test
RestTemplate
code)
spring-ws-test
@Controller
classes through @MVC infrastructure
String 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"));
request/response
from spring-test
DispatcherServlet
replacement
// XML config
MockMvc mockMvc =
xmlConfigSetup("classpath:appContext.xml")
.activateProfiles(..)
.configureWebAppRootDir(warDir, false)
.build();
// Java config
MockMvc mockMvc =
annotationConfigSetup(WebConfig.class)
.activateProfiles(..)
.configureWebAppRootDir(warDir, false)
.build();
MockMvc mockMvc =
standaloneSetup(new PersonController())
.setMessageConverters(..)
.setValidator(..)
.setConversionService(..)
.addInterceptors(..)
.setViewResolvers(..)
.setLocaleResolver(..)
.build();
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();
}
}
TestContext
FrameworkWebApplicationContext
not supported yetContextLoader
spring-test-mvc
MockMvcBuilders.*
MockMvcRequestBuilders.*
MockMvcResultActions.*
MockMvc*
MockMvc*
classes in Preferences
String contextLoc = "classpath:appContext.xml";
String warDir = "src/main/webapp";
MockMvc mockMvc = xmlConfigSetup("classpath:appContext.xml")
.configureWebAppRootDir(warDir, false)
.build()
// ...
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))
// ...
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...));
// ...
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());
// ...
RestTemplate restTemplate = ... ;
MockRestServiceServer.createServer(restTemplate)
.expect(requestTo(String))
.andExpect(method(HttpMethod))
.andExpect(body(String))
.andExpect(headerContains(String, String))
.andRespond(withResponse(String, HttpHeaders));
github.com/SpringSource/spring-test-mvc
<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>