spring-boog-測試打樁-Mockito
阿新 • • 發佈:2018-12-07
Mockito用於測試時進行打樁處理;通過它可以指定某個類的某個方法在什麼情況下返回什麼樣的值。
例如:測試 controller時,依賴 service,這個時候就可以假設當呼叫 service 某個方法時返回指定的某些值,從而來降低引用類所帶來的測試複雜度增加的影響。Mockito就用於這種場景。
Mockito常用測試場景描述如下:
- 指定打樁物件的返回值
- 判斷某個打樁物件的某個方法被呼叫及呼叫的次數
- 指定打樁物件丟擲某個特定異常
Mockito的使用,一般有以下幾種組合:
- do/when:包括doThrow(…).when(…)/doReturn(…).when(…)/doAnswer(…).when(…)
- given/will:包括given(…).willReturn(…)/given(…).willAnswer(…)
- when/then: 包括when(…).thenReturn(…)/when(…).thenAnswer(…)
指定打樁物件返回值
通過Mockito指定打樁物件的返回值時,可以通過以下方式進行:
given
given用於對指定方法進行返回值的定製,它需要與will開頭的方法一起使用,will開頭的方式根據其接收引數的不同,又分成兩類:一是接收直接值的,如直接指定返回結果為某個常量;二是接收Answer引數的,可以騎過Answer類的answer方法來根據傳入引數定製返回結果。
Answer物件
我們實際針對的一般是某個類的某個方法;這個方法可能會有輸入引數;考慮這種場景:如果要假設打樁的這個方法,在某個輸入時返回值A;在另外一個輸入時返回值為B;這種場景就可以通過Answer類來實現。
案例
@RunWith(SpringRunner.class) @SpringBootTest public class LearnController2Test { @Autowired private WebApplicationContext wac; private MockMvc mvc; private MockHttpSession session; /** * 1. 對於不需要返回的任何值的類的所有方法,可以直接使用MockBean * 2. @MockBean 會代理已有的bean的方法,不會執行真實 bean 的具體方法。 */ @MockBean private LearnService learnService; @Before public void setupMockMvc() { //初始化MockMvc物件 mvc = MockMvcBuilders.webAppContextSetup(wac).build(); //構建session session = new MockHttpSession(); User user = new User("root", "root"); //攔截器那邊會判斷使用者是否登入,所以這裡注入一個使用者 session.setAttribute("user", user); } /** * 獲取教程測試用例 * <p> * get 請求 * <p> * controller 依賴 service 的方法,這裡給 service 方法打樁,不執行真實的方法 * * @throws Exception */ @Test public void qryLearn() throws Exception { LearnResource learnResource = new LearnResource(); learnResource.setUrl("http://www.baidu.com"); learnResource.setTitle("zhang"); learnResource.setAuthor("zhang"); learnResource.setId(10L); // 當呼叫 selectByKey 函式時,返回指定的值 given(this.learnService.selectByKey(Mockito.any())).willAnswer(new Answer<Object>() { /** * InvocationOnMock 通過它可以獲取打樁方法的實際傳入引數清單 * @param invocationOnMock * @return * @throws Throwable */ @Override public Object answer(InvocationOnMock invocationOnMock) throws Throwable { Long argumentAt = invocationOnMock.getArgumentAt(0, Long.class); System.out.println("呼叫方法的實際引數: " + argumentAt); if (argumentAt.equals(Long.parseLong("1001"))) { return learnResource; } return null; } }); mvc.perform(MockMvcRequestBuilders.get("/learn/resource/1001") .contentType(MediaType.APPLICATION_JSON_UTF8) .accept(MediaType.APPLICATION_JSON_UTF8) .session(session) ) .andExpect(MockMvcResultMatchers.status().isOk()) //jsonPath用來獲取author欄位比對是否為嘟嘟MD獨立部落格,不是就測試不通過 .andExpect(MockMvcResultMatchers.jsonPath("$.author").value("嘟嘟MD獨立部落格")) .andExpect(MockMvcResultMatchers.jsonPath("$.title").value("Spring Boot乾貨系列")) .andDo(MockMvcResultHandlers.print()); } }
參考
https://blog.csdn.net/icarusliu/article/details/78860351