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);