- 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:
@EnableWebMvc@WebAppConfiguration@ContextConfiguration(classes = { FooController.class, FooImpl.class })public class SpringMvc_1_Test extends AbstractTestNGSpringContextTests {@Autowiredprivate WebApplicationContext wac;private MockMvc mvc;@BeforeMethodpublic void prepareMockMvc() {this.mvc = webAppContextSetup(wac).build();}@Testpublic void testController() throws Exception {this.mvc.perform(get("/foo/check-code-dup").param("code", "123")).andDo(print()).andExpect(status().isOk()).andExpect(content().string("true"));}}
在这段代码里,主要有三个步骤:
- 将测试类标记为
@WebAppConfiguration - 通过
webAppContextSetup(wac).build()构建MockMvc - 利用
MockMvc对结果进行判断
例子2:Spring + Mock
在例子1里,FooController使用了一个实体FooImpl的Bean,实际上我们也可以提供一个Foo的mock bean来做测试,这样就能够更多的控制测试过程。如果你还不知道Mock那么请看Chapter 3: 使用Mockito。
源代码SpringMvc_2_Test.java:
@EnableWebMvc@WebAppConfiguration@ContextConfiguration(classes = { FooController.class })@TestExecutionListeners(listeners = MockitoTestExecutionListener.class)public class SpringMvc_2_Test extends AbstractTestNGSpringContextTests {@Autowiredprivate WebApplicationContext wac;@MockBeanprivate Foo foo;private MockMvc mvc;@BeforeMethodpublic void prepareMockMvc() {this.mvc = webAppContextSetup(wac).build();}@Testpublic void testController() throws Exception {when(foo.checkCodeDuplicate(anyString())).thenReturn(true);this.mvc.perform(get("/foo/check-code-dup").param("code", "123")).andDo(print()).andExpect(status().isOk()).andExpect(content().string("true"));}}
例子3:Spring Boot
Spring Boot提供了@WebMvcTest更进一步简化了对于Spring MVC的测试,我们提供了对应例子1的Spring Boot版本。
源代码BootMvc_1_Test.java:
@WebMvcTest@ContextConfiguration(classes = { FooController.class, FooImpl.class })public class BootMvc_1_Test extends AbstractTestNGSpringContextTests {@Autowiredprivate MockMvc mvc;@Testpublic void testController() throws Exception {this.mvc.perform(get("/foo/check-code-dup").param("code", "123")).andDo(print()).andExpect(status().isOk()).andExpect(content().string("true"));}}
在这里,我们不需要自己构建MockMvc,直接使用@Autowired注入就行了,是不是很方便?
例子4:Spring Boot + Mock
这个是对应例子2的Spring Boot版本,源代码BootMvc_2_Test.java:
@WebMvcTest@ContextConfiguration(classes = { FooController.class })@TestExecutionListeners(listeners = MockitoTestExecutionListener.class)public class BootMvc_2_Test extends AbstractTestNGSpringContextTests {@Autowiredprivate MockMvc mvc;@MockBeanprivate Foo foo;@Testpublic void testController() throws Exception {when(foo.checkCodeDuplicate(anyString())).thenReturn(true);this.mvc.perform(get("/foo/check-code-dup").param("code", "123")).andDo(print()).andExpect(status().isOk()).andExpect(content().string("true"));}}
参考文档
- 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
