• Chapter 5: 测试Spring MVC
    • 例子1:Spring
    • 例子2:Spring + Mock
    • 例子3:Spring Boot
    • 例子4:Spring Boot + Mock
    • 参考文档

    Chapter 5: 测试Spring MVC

    Spring Testing Framework提供了Spring MVC Test Framework,能够很方便的来测试Controller。同时Spring Boot也提供了Auto-configured Spring MVC tests更进一步简化了测试需要的配置工作。

    本章节将分别举例说明在不使用Spring Boot和使用Spring Boot下如何对Spring MVC进行测试。

    例子1:Spring

    测试Spring MVC的关键是使用MockMvc对象,利用它我们能够在不需启动Servlet容器的情况下测试Controller的行为。

    源代码SpringMvc_1_Test.java:

    1. @EnableWebMvc
    2. @WebAppConfiguration
    3. @ContextConfiguration(classes = { FooController.class, FooImpl.class })
    4. public class SpringMvc_1_Test extends AbstractTestNGSpringContextTests {
    5. @Autowired
    6. private WebApplicationContext wac;
    7. private MockMvc mvc;
    8. @BeforeMethod
    9. public void prepareMockMvc() {
    10. this.mvc = webAppContextSetup(wac).build();
    11. }
    12. @Test
    13. public void testController() throws Exception {
    14. this.mvc.perform(get("/foo/check-code-dup").param("code", "123"))
    15. .andDo(print())
    16. .andExpect(status().isOk())
    17. .andExpect(content().string("true"));
    18. }
    19. }

    在这段代码里,主要有三个步骤:

    1. 将测试类标记为@WebAppConfiguration
    2. 通过webAppContextSetup(wac).build()构建MockMvc
    3. 利用MockMvc对结果进行判断

    例子2:Spring + Mock

    在例子1里,FooController使用了一个实体FooImpl的Bean,实际上我们也可以提供一个Foo的mock bean来做测试,这样就能够更多的控制测试过程。如果你还不知道Mock那么请看Chapter 3: 使用Mockito。

    源代码SpringMvc_2_Test.java:

    1. @EnableWebMvc
    2. @WebAppConfiguration
    3. @ContextConfiguration(classes = { FooController.class })
    4. @TestExecutionListeners(listeners = MockitoTestExecutionListener.class)
    5. public class SpringMvc_2_Test extends AbstractTestNGSpringContextTests {
    6. @Autowired
    7. private WebApplicationContext wac;
    8. @MockBean
    9. private Foo foo;
    10. private MockMvc mvc;
    11. @BeforeMethod
    12. public void prepareMockMvc() {
    13. this.mvc = webAppContextSetup(wac).build();
    14. }
    15. @Test
    16. public void testController() throws Exception {
    17. when(foo.checkCodeDuplicate(anyString())).thenReturn(true);
    18. this.mvc.perform(get("/foo/check-code-dup").param("code", "123"))
    19. .andDo(print())
    20. .andExpect(status().isOk())
    21. .andExpect(content().string("true"));
    22. }
    23. }

    例子3:Spring Boot

    Spring Boot提供了@WebMvcTest更进一步简化了对于Spring MVC的测试,我们提供了对应例子1的Spring Boot版本。

    源代码BootMvc_1_Test.java:

    1. @WebMvcTest
    2. @ContextConfiguration(classes = { FooController.class, FooImpl.class })
    3. public class BootMvc_1_Test extends AbstractTestNGSpringContextTests {
    4. @Autowired
    5. private MockMvc mvc;
    6. @Test
    7. public void testController() throws Exception {
    8. this.mvc.perform(get("/foo/check-code-dup").param("code", "123"))
    9. .andDo(print())
    10. .andExpect(status().isOk())
    11. .andExpect(content().string("true"));
    12. }
    13. }

    在这里,我们不需要自己构建MockMvc,直接使用@Autowired注入就行了,是不是很方便?

    例子4:Spring Boot + Mock

    这个是对应例子2的Spring Boot版本,源代码BootMvc_2_Test.java:

    1. @WebMvcTest
    2. @ContextConfiguration(classes = { FooController.class })
    3. @TestExecutionListeners(listeners = MockitoTestExecutionListener.class)
    4. public class BootMvc_2_Test extends AbstractTestNGSpringContextTests {
    5. @Autowired
    6. private MockMvc mvc;
    7. @MockBean
    8. private Foo foo;
    9. @Test
    10. public void testController() throws Exception {
    11. when(foo.checkCodeDuplicate(anyString())).thenReturn(true);
    12. this.mvc.perform(get("/foo/check-code-dup").param("code", "123"))
    13. .andDo(print())
    14. .andExpect(status().isOk())
    15. .andExpect(content().string("true"));
    16. }
    17. }

    参考文档

    • Loading a WebApplicationContext
    • Spring MVC Test Framework
    • Spring MVC Official Sample Tests
    • Spring MVC showcase - with full mvc test
    • Auto-configured Spring MVC tests
    • Spring Framework Testing
    • Spring Boot Testing
    • Spring Guides - Testing the Web Layer