Spring MVC Test Framework建立在Servlet API mock objects基础上,他不需要一个运行的Servlet容器, 不需要,不需要,不需要! 他使用DispatcherServlet来提供完整Spring MVC的支持,使用TestContext framework来加载实际的Spring各个配置。
Server-Side Tests
Spring MVC Test的目的:提供一种有效的利用DispatcherServlet所伴生的requests和responses来测试controller的方式。 例如
mockMvc.perform(post("/persons")) .andDo(print()) // static import from MockMvcResultHandlers, can print all the available result data .andExpect(status().isOk()) .andExpect(model().attributeHasErrors("person"));
// class body... } @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration public class MyWebAppTest { @Autowired private WebApplicationContext wac;
@Test public void databaseTest { ResourceDatabasePopulator populator = new ResourceDatabasePopulator(); populator.addScripts( new ClassPathResource("test-schema.sql"), new ClassPathResource("test-data.sql")); populator.setSeparator("@@"); populator.execute(this.dataSource); // execute code that uses the test schema and data }
//1 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration @Sql("/test-schema.sql") public class DatabaseTests {
@Test public void emptySchemaTest { // execute code that uses the test schema without any test data }
@Test @Sql({"/test-schema.sql", "/test-user-data.sql"}) public void userTest { // execute code that uses the test schema and test data } }
//1 @Test @Sql(scripts = "/test-schema.sql", config = @SqlConfig(commentPrefix = "`")) @Sql("/test-user-data.sql") public void userTest { // execute code that uses the test schema and test data } //3 @Test @SqlGroup({ @Sql(scripts = "/test-schema.sql", config = @SqlConfig(commentPrefix = "`")), @Sql("/test-user-data.sql") )} public void userTest { // execute code that uses the test schema and test data } //4 @Test @Sql( scripts = "create-test-data.sql", config = @SqlConfig(transactionMode = ISOLATED) ) @Sql( scripts = "delete-test-data.sql", config = @SqlConfig(transactionMode = ISOLATED), executionPhase = AFTER_TEST_METHOD ) public void userTest { // execute code that needs the test data to be committed // to the database outside of the test's transaction }
TestContext Framework支持类
Spring JUnit Runner
1 2 3 4 5 6 7 8 9
@RunWith(SpringJUnit4ClassRunner.class) @TestExecutionListeners({}) public class SimpleTest {
@Test public void testMethod() { // execute test logic... } }
// 1) xml @ContextConfiguration("/test-config.xml") public class XmlApplicationContextTests { // class body... } // 2) @Configuration Class @ContextConfiguration(classes = TestConfig.class) public class ConfigClassApplicationContextTests { // class body... } // 3) `ApplicationContextInitializer` Class @ContextConfiguration(initializers = CustomContextIntializer.class) public class ContextInitializerTests { // class body... } // 4) ContextLoader @ContextConfiguration(locations = "/test-context.xml", loader = CustomContextLoader.class) public class CustomLoaderXmlApplicationContextTests { // class body... }
@ContextConfiguration @WebAppConfiguration public class WebAppTests { // class body... } @ContextConfiguration @WebAppConfiguration("classpath:test-web-resources") public class WebAppTests { // class body... }
@ContextHierarchy({ @ContextConfiguration("/parent-config.xml"), @ContextConfiguration("/child-config.xml") }) public class ContextHierarchyTests { // class body... }
1 2 3 4 5 6 7 8
@WebAppConfiguration @ContextHierarchy({ @ContextConfiguration(classes = AppConfig.class), @ContextConfiguration(classes = WebConfig.class) }) public class WebIntegrationTests { // class body... }
// BEFORE_CLASS @DirtiesContext(classMode = BEFORE_CLASS) public class FreshContextTests { // some tests that require a new Spring container } //default class mode : `AFTER_CLASS` @DirtiesContext public class ContextDirtyingTests { // some tests that result in the Spring container being dirtied } // BEFORE_EACH_TEST_METHOD @DirtiesContext(classMode = BEFORE_EACH_TEST_METHOD) public class FreshContextTests { // some tests that require a new Spring container } // AFTER_EACH_TEST_METHOD @DirtiesContext(classMode = AFTER_EACH_TEST_METHOD) public class ContextDirtyingTests { // some tests that result in the Spring container being dirtied } // BEFORE_METHOD @DirtiesContext(methodMode = BEFORE_METHOD) @Test public void testProcessWhichRequiresFreshAppCtx() { // some logic that requires a new Spring container } //default method mode `AFTER_METHOD` @DirtiesContext @Test public void testProcessWhichDirtiesAppCtx() { // some logic that results in the Spring container being dirtied }
@TestExecutionListeners
@Commit
@Rollback
@BeforeTransaction
@AfterTransaction
@Sql
@SqlConfig
@SqlGroup
Standard Annotation Support
Spring TestContext Framework 支持下列标准的注解
@Autowired
@Qualifier
@Resource (javax.annotation) if JSR-250 is present
@Inject (javax.inject) if JSR-330 is present
@Named (javax.inject) if JSR-330 is present
@PersistenceContext (javax.persistence) if JPA is present
@PersistenceUnit (javax.persistence) if JPA is present
@IfProfileValue(name="java.vendor", value="Oracle Corporation") @Test public void testProcessWhichRunsOnlyOnOracleJvm() { // some logic that should run only on Java VMs from Oracle Corporation } @IfProfileValue(name="test-groups", values={"unit-tests", "integration-tests"}) @Test public void testProcessWhichRunsForUnitOrIntegrationTestGroups() { // some logic that should run only for unit and integration test groups }
@ProfileValueSourceConfiguration
@Timed
1 2 3 4
@Timed(millis=1000) public void testProcessWithOneSecondTimeout() { // some logic that should not take longer than 1 second to execute }
@Repeat
1 2 3 4 5
@Repeat(10) @Test public void testProcessRepeatedly() { // ... }
@Configuration public class WebConfig extends DelegatingWebMvcConfiguration {
@Override public void addInterceptors(InterceptorRegistry registry){ // ... }
@Override @Bean public RequestMappingHandlerAdapter requestMappingHandlerAdapter() { // Create or let "super" create the adapter // Then customize one of its properties }