Mock使用場景:git
(1)建立所需的DB數據可能須要很長時間,如:調用別的接口,模擬不少數據,確保發佈版本接口可用github
(2)調用第三方API接口,測試很慢,spring
(3)編寫知足全部外部依賴的測試可能很複雜,複雜到不值得編寫,Mock模擬內部或外部依賴能夠幫助咱們解決這些問題數據庫
(4)隔離當前方法使用的的全部依賴,讓咱們更加專一於單個單元,忽略其調用的代碼的內部工做原理cookie
Mock的好處:網絡
(1)Mock能夠用來解除測試對象對外部服務的依賴(好比數據庫,第三方接口等),使得測試用例能夠獨立運行。無論是傳統的單體應用,仍是如今流行的微服務,這點都特別重要,由於任何外部依賴的存在都會極大的限制測試用例的可遷移性和穩定性。session
(2)Mock的第二個好處是替換外部服務調用,提高測試用例的運行速度。任何外部服務調用至少是跨進程級別的消耗,甚至是跨系統、跨網絡的消耗,而Mock能夠把消耗下降到進程內。好比原來一次秒級的網絡請求,經過Mock能夠降至毫秒級,整整3個數量級的差異。app
(3)Mock的第三個好處是提高測試效率。這裏說的測試效率有兩層含義。第一層含義是單位時間運行的測試用例數,這是運行速度提高帶來的直接好處。而第二層含義是一個測試人員單位時間建立的測試用例數。函數
經常使用的Mock工具備jMock 、EasyMock 、Mockito等,但都有一個共同的缺點:不能mock靜態、final、私有方法等。而PowerMock可以完美的彌補其餘Mock工具的不足,若是須要mock靜態方法。須要引入PowerMock。spring-boot
Springboot的 spring-boot-starter-test 已包含了Mockito,能夠在Springboot項目裏面直接使用。
PowerMock使用技巧
① @RunWith(PowerMockRunner.class)和@PrepareForTest(PowerMockClass.Class)這兩個註解必定要加,不然PowerMock無效。@PrepareForTest中須要添加被測試的類,以及被測方法中須要mock的static方法所屬的類。
若是有多個類要添加,則格式爲:
@PrepareForTest({Class1.Calss,Class2.Class}).
② PowerMock各方法的語法(通常方法與Mockito用法一致):
(1) void靜態:PowerMockito.mockStatic(xxx.Class);
PowerMockito.doNothing().when(mock,」methodName」,arg1,arg2);
(2)有返回值靜態:PowerMockito.mockStatic(xxx.Class);
PowerMockito.when(mock.method()).thenReturn(value);
(3)私有有返回值靜態:PowerMockito.mock(xxx.Class);
PowerMockito.when(mock,」methodName」,arg1,arg2).thenReturn(value);
(4)構造函數:PowerMockito.mock(xxx.Class);
PowerMockito.whenNew(xxx.Class).withAnyArguments().thenReturn();
測試示例:
@RequestMapping(value = "", method = RequestMethod.POST) public ReturnMsg crossDomainSetCookie(HttpServletRequest request, HttpServletResponse response, String name, String value) { Cookie[] cookies = request.getCookies(); for (Cookie c : cookies) { System.out.println("CookieName: " + c.getName() + " CookieValue: " + c.getValue()); } HttpSession session = request.getSession(); Enumeration<String> attributeNames = session.getAttributeNames(); while (attributeNames.hasMoreElements()) { String element = attributeNames.nextElement(); System.out.println(element); } try { String authType = request.getAuthType(); System.out.println("auth type is:" + authType); } catch (Exception e) { System.out.println("exception message:" + e.getMessage()); } int status = response.getStatus(); System.out.println("the response status is:" + status); return ReturnMsg.generatorSuccessMsg("success"); }
測試代碼
@RunWith(SpringRunner.class) @SpringBootTest public class StudentControllerTest { /** * 自動注入 */ @Autowired private StudentController studentController; @Test public void crossDomainSetCookie() { HttpServletRequest request = Mockito.mock(HttpServletRequest.class); //Mock帶參方法返回值 Mockito.when(request.getHeader("Origin")).thenReturn("127.0.0.1"); Cookie[] cookies = {new Cookie("Login", "true")}; //設置無參方法返回值 Mockito.when(request.getCookies()).thenReturn(cookies); //Mock對象實例 HttpSession session = Mockito.mock(HttpSession.class); Enumeration<String> en = Mockito.mock(Enumeration.class); //Mock集合對象返回多個值,第一次返回值true,第二次返回值ture,第三次及之後返回false Mockito.when(en.hasMoreElements()).thenReturn(true).thenReturn(true).thenReturn(false); Mockito.when(en.nextElement()).thenReturn("login").thenReturn("loginFlag"); Mockito.when(session.getAttributeNames()).thenReturn(en); Mockito.when(request.getSession()).thenReturn(session); //Mock方法調用時拋出異常 doThrow(new IllegalArgumentException("nothing auth type!")).when(request).getAuthType(); HttpServletResponse response = Mockito.mock(HttpServletResponse.class); Mockito.when(response.getStatus()).thenReturn(1); String value = "e10adc3949ba59abbe56e057f20f883e"; ReturnMsg msg = studentController.crossDomainSetCookie(request, response, "test", value); System.out.println(msg.toString()); } }
GItHub源碼:https://github.com/lovelifeming/Resource/tree/master/SpringBoots/SpringBootDemo
備註:做者:Shengming Zeng博客:http://www.cnblogs.com/zengming/嚴正聲明:1.因爲本博客部分資源來自互聯網,版權均歸原做者全部。轉載的目的是用於學術交流與討論學習,將不對任何資源負法律責任。2.若無心中侵犯到您的版權利益,請來信聯繫我,我會在收到信息後會儘快給予處理!3.全部資源內容僅供學習交流之用,請勿用做商業用途,謝謝。4.若有轉發請註明出處,來源於http://www.cnblogs.com/zengming/ ,謝謝合做。