对模块进行集成测试时,希望能够通过输入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>


springcloud mock_SpringBoot

创建单元测试

springcloud mock_SpringBoot_02

编写单元测试方法

 

 使用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使用

  1. mockMvc.perform执行一个请求
  2. MockMvcRequestBuilders.get(“/user/1”)构造一个请求,Post请求就用.post方法
  3. contentType(MediaType.APPLICATION_JSON_UTF8)代表发送端发送的数据格式是application/json;charset=UTF-8
  4. accept(MediaType.APPLICATION_JSON_UTF8)代表客户端希望接受的数据类型为application/json;charset=UTF-8
  5. session(session)注入一个session,这样拦截器才可以通过
  6. ResultActions.andExpect添加执行完成后的断言
  7. ResultActions.andExpect(MockMvcResultMatchers.status().isOk())方法看请求的状态响应码是否为200如果不是则抛异常,测试不通过
  8. ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情,比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息
  9. andExpect(MockMvcResultMatchers.jsonPath(“$.data.rows[0].id”).value(“1111111”))这里jsonPath用来获取author字段比对是否为”1111111”,不是就测试不通过

 基于RESTful风格的Controller测试


springcloud mock_单元测试_03

RESTful风格

 

 单元测试回滚


springcloud mock_json_04

单元测试回滚

 

只需要在测试方法上加上@Transactional

前提是MySql数据库引擎是InnoDB,如果流程引擎不是InnoDB,需要修改。