單元測試-Mockito(一)

1.概述

Java常用的單元測試框架有:Junit,TestNg,Easymock,Mockito,PowerMock。

本文主要討論Mockito框架,是基于學習mockito文檔和自己實操驗證理解而來,mockito文檔中文地址:https://github.com/hehonghui/mockito-doc-zh,感謝并向他們致敬。

開始之前,先談談對單元測試的理解,就不照搬普世定義了,只談談個人淺薄認識。

所謂單元測試unit test也叫打樁測試,我個人理解就是針對一個類或者說類中的一個方法,編寫測試代碼,在測試代碼中做一些假設性的輸入,斷言被測試的代碼是否能得出自己想要的邏輯結果。

寫單元測試的好處,我個人工作經歷認為比較明顯的是:單元測試都跑過的代碼,基本前后臺聯(lián)調沒有問題;再者,對代碼重構后,如果保持原來的輸入輸出不變,那么跑一遍單元測試,算是給自己吃顆定心丸。當然單元測試也有缺點,就是增加了工作代碼量,需要花費程序員更多的時間,視項目具體情況而使用吧。

2.實操

實操之前記得導入mockito的jar包(import staticorg.mockito.Mockito.*; ),copy 然后alt+enter讓maven自動增加就行:


image

或者把以下依賴增加到pom文件中:

<dependency>
   <groupId>org.mockito</groupId>
   <artifactId>mockito-all</artifactId>
   <version>1.9.5</version>
   <scope>test</scope>
 </dependency>

2.1 驗證某些行為(方法)

一旦mock對象被創(chuàng)建了,mock對象會記住所有的交互。然后你就可能選擇性的驗證你感興趣的交互。如果驗證時,和使用中操作的不同,或者增加的對象不是一個,或者增加方法都會驗證失敗,如圖所示:
圖片.png

2.2做測試樁 (Stub)

測試樁可以理解為對mock對象進行的一些預期操作,mock函數(shù)默認返回的是null。
圖片.png

2.2參數(shù)匹配器

參數(shù)匹配器指anyInt(),anyString()能代替復雜的參數(shù)匹配,讓測試代碼簡潔。

 when(mockedList.get(anyInt())).thenReturn("element");
 verify(mock).someMethod(anyInt(), anyString(), eq("third argument"));

2.3驗證確切verify(mock,time(x)).operate()、最少atLeast()/最多atMost()、從未調用never()

//mocklist .add 方法指只執(zhí)行了一次
 verify(mockedList, times(1)).add("once");
 // 驗證具體的執(zhí)行次數(shù)ver
 verify(mockedList, times(3)).add("three times");
 // 使用never()進行驗證,never相當于times(0)
 verify(mockedList, never()).add("never happened");

 //verification using atLeast()/atMost()
 // 使用atLeast()/atMost()
 verify(mockedList, atLeastOnce()).add("three times");
 verify(mockedList, atLeast(2)).add("five times");
 verify(mockedList, atMost(5)).add("three times");

2.4返回值為void的函數(shù)通過Stub拋出異常范式:doThrow(exception).when().operate()

doThrow(new RuntimeException()).when(mockedList).clear();
// 調用這句代碼會拋出異常
mockedList.clear();

2.5驗證執(zhí)行順序InOrder

 List singleMock = mock(List.class);
 singleMock.add("was added first");
 singleMock.add("was added second");
 // 為該mock對象創(chuàng)建一個inOrder對象
 InOrder inOrder = inOrder(singleMock);
 // 確保add函數(shù)首先執(zhí)行的是add("was added first"),然后才是add("was added second")
 inOrder.verify(singleMock).add("was added first");
 inOrder.verify(singleMock).add("was added second");
 // B. Multiple mocks that must be used in a particular order
 // B .驗證多個mock對象的函數(shù)執(zhí)行順序
 List firstMock = mock(List.class);
 List secondMock = mock(List.class);
 //using mocks
 firstMock.add("was called first");
 secondMock.add("was called second");
 //create inOrder object passing any mocks that need to be verified in order
 // 為這兩個Mock對象創(chuàng)建inOrder對象
 InOrder inOrder = inOrder(firstMock, secondMock);
 //following will make sure that firstMock was called before secondMock
 // 驗證它們的執(zhí)行順序
 inOrder.verify(firstMock).add("was called first");
 inOrder.verify(secondMock).add("was called second");

2.6確保交互(interaction)操作不會執(zhí)行在mock對象上verifyZeroInteractions()

 mockOne.add("one");
 // 普通驗證
 verify(mockOne).add("one");
 // 驗證某個交互是否從未被執(zhí)行
 verify(mockOne, never()).add("two");
 // 驗證mock對象沒有交互過
 verifyZeroInteractions(mockTwo, mockThree);
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容