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
的知識教程都有提到,有興趣的能夠閱讀。