如何使用jmockit進行單元測試
1. Jmockit簡介
JMockit 是用以幫助開發人員編寫測試程序的一組工具和API,它完全基於 Java 5 SE 的 java.lang.instrument 包開發,內部使用 ASM 庫來修改Java的Bytecode。正是由於基於instrument,可以修改字節碼。所以這也是它強大的原因。
Jmockit可以mock的種類包含了:
1. class(abstract, final, static)
2. interface
3. enum
4. annotation
5. native
Jmockit 有兩種mock的方式:
1. Behavior-oriented(Expectations & Verifications)
2. State-oriented(MockUp<GenericType>)
通俗點講,Behavior-oriented是基於行為的mock,對mock目標代碼的行為進行模仿,更像黑盒測試。State-oriented 是基於狀態的mock,是站在目標測試代碼內部的。可以對傳入的參數進行檢查、匹配,才返回某些結果,類似白盒。而State-oriented的 new MockUp基本上可以mock任何代碼或邏輯。非常強大。
(這段介紹來自網絡轉載)
2. Jmockit實踐
使用jMockit首先要引用相關的jar包,pom文件引用如下.
<dependency> <groupId>org.jmockit</groupId> <artifactId>jmockit</artifactId> <version>1.20</version> <scope>test</scope> </dependency> <dependency> <groupId>org.jmockit</groupId> <artifactId>jmockit-coverage</artifactId> <version>1.20</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> |
2.1 示例1:模擬類
被測試方法如下:
其中NegativeTransDos的insert方法是插入數據庫。
為了測試process()方法的邏輯,希望能夠模擬dao.insert方法的返回結果,參考測試代碼如下:
可以看到使用jmockit基本有三個步驟:
(1)打樁。指定要打樁類和函數,模擬返回結果。這里是new Mockup(NegativeTransDos)。
(2)調用被測方法。被測邏輯執行過程中,之前的打樁數據生效。
(3)判斷測試結果是否符合預期。
通過以下方法來模擬類和方法。
new Mockup(類) { 模擬方法{ 控制該方法返回結果 } } |
2.2 示例2:模擬靜態方法
被測試方法如下。其中紅框是需要Mock的兩個靜態方法。通過Jmockit模擬這兩個靜態方法的返回,只關注EdaStartup方法的自身邏輯。
參考測試代碼如下:
2.3 示例3:模擬非靜態方法
被測試方法:
這里包括兩種方法的模擬:
McEventManager.getReceiver(),這個是靜態方法調用的模擬,參考2.1章節。
receiver.getEvent(),這個是普通對象方法調用。本節關注這種方法的模擬。
參考測試代碼如下:
首先需要通過 @Injectable 聲明要插樁的對象:
private McEventReceiver receiver;
之后使用以下方式來插樁:
new NonStrictExpectations() { 要模擬的方法(參數1,參數2,…) result = 返回結果 } |
Jmockit提供了很彪悍的萬能入參,這一點非常方便。包括:
2.4 示例4:模擬private靜態方法
被測代碼如下:
publicMethod()是被測試方法,其中調用了靜態成員方法privateMethod。為了摒除privateMethod的影響,需要模擬它的返回結果。
參考測試代碼如下:
test1和test2的輸出結果分別是:
2.5 示例5:模擬private非靜態方法
被測代碼如下:
publicMethod()是被測試方法,其中調用了私有非靜態成員方法privateMethod。為了摒除privateMethod的影響,需要模擬它的返回結果。
參考測試代碼如下:
對比2.5私有靜態方法的模擬可以看到略有區別。
new Expectations(XXX) 中,之前指定的是MockClass.class,這里指定的是被測試的MockClass對象。
test1和test2的輸出結果分別是:
2.6 示例6:模擬private非靜態成員變量
被測方法如下:
其中field是MockField的私有變量。我們目的是能夠模擬該私有變量的值,來關注publicMethod方法的測試。
參考測試代碼如下:
test1和test2的輸出結果分別是:
2.7 示例7:模擬private靜態成員變量
類似2.6節非靜態成員變量的模擬,參考2.4和2.5的區別。示例略。