对模块进行集成测试时,希望能够通过输入URL对Controller进行测试,如果通过启动服务器,建立http client进行测试,这样会使得测试变得很麻烦,比如,启动速度慢,测试验证不方便,依赖网络环境等,这样会导致测试无法进行,为了可以对Controller进行测试,可以通过引入MockMVC进行解决。
MockMvc实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,这样可以使得测试速度快、不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便。
MockMvcBuilder是用来构造MockMvc的构造器,其主要有两个实现:StandaloneMockMvcBuilder和DefaultMockMvcBuilder,分别对应两种测试方式,即独立安装和集成Web环境测试(此种方式并不会集成真正的web环境,而是通过相应的Mock API进行模拟测试,无须启动服务器)。对于我们来说直接使用静态工厂MockMvcBuilders创建即可。
Spring Boot中引入单元测试依赖如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
创建单元测试
编写单元测试方法
使用jsonPath检查数据
@Test
public void getInfo() throws Exception{
Map map = new HashMap<>();
map.put("usedTime", "2019/5/19 - 2019/6/19");
map.put("pageSize", 20);
map.put("pageNumber", 1);
map.put("Id", "c4f18b5e-49be-4e37-a6c5-22e12657a419");
String requestJson = JSONObject.toJSONString(map);
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/api/v2/get/get_info")
.contentType(MediaType.APPLICATION_JSON_UTF8).content(requestJson)
.accept(MediaType.APPLICATION_JSON_UTF8))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().is(200))
.andExpect(MockMvcResultMatchers.jsonPath("$.data.rows[1].id")
.value("d4179311-8fae-4d16-8106-b9b0e8f6461d"))//4dc359b7-f7c7-4039-930d-48b30995459b
.andReturn();
int status = result.getResponse().getStatus();
String content = result.getResponse().getContentAsString();
Assert.assertTrue("正确", status == 200);
Assert.assertFalse("错误", status != 200);
System.out.println("返回状态结果:" + status);
System.out.println("返回结果" + content);
}
被测试的接口入参是一个JSONObject 类型的数据,此时需要转换成String类型,Mock不支持对象的传入或者其他类型
MockMvc使用
- mockMvc.perform执行一个请求
- MockMvcRequestBuilders.get(“/user/1”)构造一个请求,Post请求就用.post方法
- contentType(MediaType.APPLICATION_JSON_UTF8)代表发送端发送的数据格式是application/json;charset=UTF-8
- accept(MediaType.APPLICATION_JSON_UTF8)代表客户端希望接受的数据类型为application/json;charset=UTF-8
- session(session)注入一个session,这样拦截器才可以通过
- ResultActions.andExpect添加执行完成后的断言
- ResultActions.andExpect(MockMvcResultMatchers.status().isOk())方法看请求的状态响应码是否为200如果不是则抛异常,测试不通过
- ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情,比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息
- andExpect(MockMvcResultMatchers.jsonPath(“$.data.rows[0].id”).value(“1111111”))这里jsonPath用来获取author字段比对是否为”1111111”,不是就测试不通过
基于RESTful风格的Controller测试
RESTful风格
单元测试回滚
单元测试回滚
只需要在测试方法上加上@Transactional
前提是MySql数据库引擎是InnoDB,如果流程引擎不是InnoDB,需要修改。