Mockito
是当前最流行的单元测试Mock
框架。咱们能够虚拟出一个外部依赖,下降测试组件之间的耦合度,只注重代码的流程与结果,真正地实现测试目的。spring
Mock
的中文译为仿制的,模拟的,虚假的。对于测试框架来讲,即构造出一个模拟/虚假的对象,使咱们的测试能顺利进行下去。json
ito
实际上是input to output
springboot
Mockito
大体意思就是模拟输入和输出,用一个 虚拟的对象(Mock
对象)来建立,以便测试方法。
单元测试是为了验证咱们的代码运行正确性,咱们注重的是代码的流程以及结果的正确与否。mvc
对比真实运行代码,可能其中有一些外部依赖的构建步骤相对麻烦,测试用例显得复杂难懂,会大大增长单元测试的工做。app
使用Mock
,咱们能够虚拟出一个外部依赖,只注重代码的流程与结果,真正地实现测试目的。框架
A
依赖B
,但B
并无开发,此时就能够Mock
出一个B
)C层代码:ide
@RestController @RequestMapping("Student") public class StudentController { @Autowired StudentService studentService; @PostMapping @ResponseStatus(HttpStatus.CREATED) public Student save(@RequestBody Student student) { return studentService.save(student); } }
M层代码:post
接口单元测试
public interface StudentService { Student save(Student student); }
实现类:测试
@Service public class StudentServiceImpl implements StudentService { @Autowired StudentRepository studentRepository; @Override public Student save(Student student) { return studentRepository.save(student); } }
以save这个方法为例,进行C
M
层测试
测试C层:
public class StudentControllerTest { @Test public void save() throws Exception { // 模拟发送请求 logger.info("准备输入数据"); String url = "Student"; JSONObject studentJsonObject = new JSONObject(); JSONObject klassJsonObject = new JSONObject(); studentJsonObject.put("sno", "学号测试"); studentJsonObject.put("name", "姓名测试"); klassJsonObject.put("id", -1); studentJsonObject.put("klass", klassJsonObject); logger.info("发起请求"); MvcResult mvcResult = this.mockMvc.perform( MockMvcRequestBuilders.post(url) .content(studentJsonObject.toString() .contentType(MediaType.APPLICATION_JSON_UTF8)) .andExpect(MockMvcResultMatchers.status().is(201) .andDo(MockMvcResultHandlers.print()) .andReturn(); // 测试传入的值是否符合预期 logger.info("新建参数捕获器"); ArgumentCaptor<Student> studentArgumentCaptor = ArgumentCaptor.forClass(Student.class); Mockito.verify(studentService).save(studentArgumentCaptor.capture()); Student passedStudent = studentArgumentCaptor.getValue(); logger.info("断言捕获的对与咱们前面传入的值的相同"); Assertions.assertThat(passedStudent.getSno()).isEqualTo("学号测试"); Assertions.assertThat(passedStudent.getName()).isEqualTo("姓名测试"); Assertions.assertThat(passedStudent.getId()).isNull(); Assertions.assertThat(passedStudent.getKlass().getId()).isEqualTo(-1L); // 测试返回的值是否符合预期 logger.info("准备服务层被调用后的返回数据"); Student returnStudent = new Student(); returnStudent.setId(1L); returnStudent.setSno("测试返回学号"); returnStudent.setName("测试返回姓名"); returnStudent.setKlass(new Klass()); returnStudent.getKlass().setId(1L); Mockito.when(studentService.save(Mockito.any(Student.class))).thenReturn(returnStudent); logger.info("获取返回的值并断言此值与咱们模拟的返回值相同"); String stringReturn = mvcResult.getResponse().getContentAsString(); DocumentContext documentContext = JsonPath.parse(stringReturn); LinkedHashMap studentHashMap = documentContext.json(); Assertions.assertThat(studentHashMap.get("id")).isEqualTo(1); Assertions.assertThat(studentHashMap.get("sno")).isEqualTo("测试返回学号"); Assertions.assertThat(studentHashMap.get("name")).isEqualTo("测试返回姓名"); LinkedHashMap klassHashMap = (LinkedHashMap) studentHashMap.get("klass"); Assertions.assertThat(klassHashMap.get("id")).isEqualTo(1); } }
测试M层:
public class StudentServiceImplTest { @Test public void save() { logger.info("准备传入的数据"); Student passStudent = new Student(); logger.info("调用服务层"); Student returnStudent = studentService.save(passStudent); logger.info("准备返回的数据"); Student mockReturnStudent = new Student(); Mockito.when(studentRepository.save(Mockito.any(Student.class))).thenReturn(mockReturnStudent); logger.info("新建参数捕获器"); ArgumentCaptor<Student> studentArgumentCaptor =ArgumentCaptor.forClass(Student.class); Mockito.verify(studentRepository).save(studentArgumentCaptor.capture()); logger.info("断言获取的数据与传入的相同"); Assertions.assertThat(studentArgumentCaptor.getValue()).isEqualTo(passStudent); logger.info("断言返回的数据与输出的相同"); Assertions.assertThat(returnStudent).isEqualTo(mockReturnStudent); } }
总感受当时能搞明白啥意思,可是时间一长本身仍是有点懵,还须要捋一下思路才行,全部在此简单记录总结一下。
参考SpringBoot+Angular入门实例教程[4.5.9] 关于更多详细的SpringBoot
与 Angular
的知识教程都有提到,有兴趣的能够阅读。