目录
一、基本概念
二、主要特点
三、使用场景
四、工作原理
五、示例代码
接口创建
测试类创建
六、注解解释
@AutoConfigureMockMvc
@WebMvcTest
一、基本概念
MockMvc实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用。它允许开发者创建一个虚拟的HTTP环境,发送各种HTTP请求,并验证控制器的处理结果。通过MockMvc,开发者可以模拟用户的请求行为,测试控制器层的业务逻辑,而不需要启动完整的Web服务器。
二、主要特点
- 无需启动服务器:MockMvc可以在不启动实际服务器的情况下对Spring MVC控制器进行测试,从而加快了测试速度并减少了测试环境的复杂性。
- 支持多种HTTP请求:MockMvc支持GET、POST、PUT、DELETE等多种HTTP请求方法,可以模拟用户在实际应用中可能发出的各种请求。
- 验证响应结果:MockMvc提供了丰富的验证工具,可以对控制器的响应状态码、响应体、响应头等进行验证,确保控制器的行为符合预期。
- 易于集成:MockMvc可以与其他测试框架(如JUnit)和测试工具(如Hamcrest)结合使用,提供了灵活的测试选项。
三、使用场景
- 单元测试:对控制器层进行单元测试,验证控制器的业务逻辑是否正确。
- 集成测试:虽然MockMvc测试更接近集成测试(因为它测试了控制器、视图和模型的交互),但由于它不需要部署应用程序或连接到数据库,因此通常仍然被归类为单元测试。然而,通过MockMvc,开发者可以在一定程度上模拟集成测试的场景。
- 接口调试:在没有实际后端服务的情况下,使用MockMvc可以测试控制器与后端服务的交互,帮助开发者调试和验证接口行为。
四、工作原理
- 构造MockMvc实例:使用MockMvcBuilder构造一个MockMvc的实例,或者在测试类上添加@WebMvcTest注解后通过自动注入创建MockMvc实例。
- 执行测试:通过MockMvc的perform方法执行一个HTTP请求,该方法接受一个RequestBuilder对象的参数,用于调用控制器的业务处理逻辑。
- 获得返回结果对象:perform方法返回一个实现了ResultActions接口的对象(即控制器的响应结果),开发者可以在该对象上进行下一步的操作,如进行验证、执行一个处理或继续将结果封装为MvcResult对象。
- 对结果进行验证:对ResultActions对象进行验证时,接受一个实现了ResultMatcher接口的对象作为参数。开发者可以实现两种验证方式:对请求结果进行验证或对请求返回的内容进行验证。
五、示例代码
接口创建
-
创建一个简单的Controller接口,获取版本结束时间
@RestController
@RequestMapping("/MockMvc")
public class MockMvcController {
@Autowired
private AITestService aITestService;
@PostMapping(value = "/getGroupVersionEndTime")
public String getGroupVersionEndTime(@RequestBody GetGroupVersionEndTimeRequest request) {
return aITestService.getGroupVersionEndTime(request);
}
}
测试类创建
创建测试类,使用MockMvc进行测试,这里有两种不同的测试方式
- 一种是使用
@AutoConfigureMockMvc
与@SpringBootTest
一起使用,用于集成测试。它会自动配置MockMvc
实例,且测试范围是整个Spring Boot应用程序的上下文。这意味着在测试过程中,会加载整个应用程序的Bean和配置,包括服务层、数据层等组件。因此,这种测试方式相对较重,但能够更全面地验证应用程序的行为。
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MockMvcControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testGetGroupVersionEndTime() throws Exception {
String request = "{\"allocateGroupCode\":\"G000000003\",\"effStartTime\":\"2020-08-05\",\"effStatus\":\"A\"}";
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/MockMvc/getGroupVersionEndTime")
.contentType("application/json;charset=UTF-8")
.content(request))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.responseMsg").value("请求成功"))
.andReturn();
String content = mvcResult.getResponse().getContentAsString();
System.out.println(content);
}
}
- 一种是使用
@WebMvcTest
这个注解专门用于测试Spring MVC的控制器层。它会自动配置与MVC相关的组件,如控制器、视图解析器、消息转换器等,但不会加载整个应用程序的上下文。因此,@WebMvcTest
提供了一种轻量级的测试方式,专注于控制器层的行为验证,可以理解为切片测试。
import static org.mockito.Mockito.when;
@RunWith(SpringJUnit4ClassRunner.class)
@WebMvcTest(MockMvcController.class)
public class MockMvcControllerWebMvcTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private AITestService aiTestService; // 如果控制器依赖于服务,可以使用@MockBean注解来模拟这些服务
@Test
public void testGetGroupVersionEndTime() throws Exception {
String request1 = "{\"allocateGroupCode\":\"G000000003\",\"effStartTime\":\"2020-08-05\",\"effStatus\":\"A\"}";
GetGroupVersionEndTimeRequest request = new GetGroupVersionEndTimeRequest();
request.setAllocateGroupCode("G000000003");
request.setEffStartTime("2020-08-05");
request.setEffStatus("A");
// 模拟服务方法的返回值
when(aiTestService.getGroupVersionEndTime(request)).thenReturn("2025-02-26");
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/MockMvc/getGroupVersionEndTime")
.contentType("application/json;charset=UTF-8")
.content(request1))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn();
String content = mvcResult.getResponse().getContentAsString();
System.out.println(content);
}
}
六、注解解释
@AutoConfigureMockMvc
1. 功能:
@AutoConfigureMockMvc
是一个自动配置注解,用于自动配置MockMvc
实例。- 它通常与其他测试注解(如
@SpringBootTest
)一起使用,以便在集成测试中模拟HTTP请求。
2. 使用场景:
- 适用于需要完整Spring Boot上下文的集成测试。
- 可以测试整个应用程序的MVC层,包括控制器、服务、存储库等。
3. 特点:
- 自动配置
MockMvc
实例,无需手动创建。 - 可以与
@SpringBootTest
结合使用,加载完整的应用程序上下文。
@WebMvcTest
1. 功能:
@WebMvcTest
是一个切片测试注解,专门用于测试Spring MVC控制器层。- 它会自动配置Spring MVC基础设施,但不会加载完整的应用程序上下文。
2. 使用场景:
- 适用于只需要测试控制器层的单元测试。
- 可以快速测试控制器的行为,而不需要启动整个应用程序。
3. 特点:
- 只加载与MVC相关的组件,如控制器、过滤器、拦截器等。
- 默认情况下,不会加载服务层和存储库层的bean,可以通过
@MockBean
注解手动模拟这些依赖。 - 提供了更快的测试启动时间和更轻量级的测试环境。
总结
@AutoConfigureMockMvc
适用于需要完整Spring Boot上下文的集成测试,可以测试整个应用程序的MVC层。@WebMvcTest
适用于只需要测试控制器层的单元测试,提供更快的测试启动时间和更轻量级的测试环境。
选择哪个注解取决于你的测试需求:
- 如果你需要测试整个应用程序的MVC层,并且需要完整的Spring Boot上下文,使用
@AutoConfigureMockMvc
。 - 如果你只需要测试控制器层的行为,并且希望测试环境更轻量级,使用
@WebMvcTest
。
综上所述,MockMvc是一个强大的测试工具,可以帮助开发者高效地测试Spring MVC控制器的行为。通过模拟HTTP请求和验证响应结果,开发者可以确保控制器的业务逻辑正确无误。