使用Powermock進行單元測試,以及常見問題的處理


1. 引言

在進行單元測試時,經常遇到被測方法依賴外部對象和環境,如需要數據庫連接,網絡通信依賴等,需要進行大量的初始化工作,這時可以采用powermock+mockito對被測對象進行模擬,通過錄放的形式解決此類問題。

Mockito 是一個針對 Java 的單元測試模擬框架,它與 EasyMock 和 jMock 很相似,都是為了簡化單元測試過程中測試上下文 ( 或者稱之為測試驅動函數以及樁函數 ) 的搭建而開發的工具。

PowerMock 也是一個單元測試模擬框架,它是在其它單元測試模擬框架的基礎上做出的擴展。通過提供定制的類加載器以及一些字節碼篡改技巧的應用,PowerMock 現了對靜態方法、構造方法、私有方法以及 Final 方法的模擬支持,對靜態初始化過程的移除等強大的功能。

2. 使用實例

模擬接口返回

首先對接口進行mock,然后錄制相關行為

InterfaceToMock mock = Powermockito.mock(InterfaceToMock.class)

Powermockito.when(mock.method(Params…)).thenReturn(value)

Powermockito.when(mock.method(Params..)).thenThrow(Exception)

設置對象的private屬性

需要使用whitebox向class或者對象中賦值。

如我們已經對接口盡心了mock,現在需要將此mock加入到對象中,可以采用如下方法:

Whitebox.setInternalState(Object object, String fieldname, Object… value);

其中object為需要設置屬性的靜態類或對象。

模擬構造函數

注意解決出現的@PowerMockIgnore("javax.management.*")問題

對於模擬構造函數,也即當出現new InstanceClass()時可以將此構造函數攔截並替換結果為我們需要的mock對象。

注意:使用時需要加入標記:

@RunWith(PowerMockRunner.class)

@PrepareForTest({ InstanceClass.class })

@PowerMockIgnore("javax.management.*")

Powermockito.whenNew(InstanceClass.class).thenReturn(Object value)

模擬靜態方法

模擬靜態方法類似於模擬構造函數,也需要加入注釋標記。

@RunWith(PowerMockRunner.class)

@PrepareForTest({ StaticClassToMock.class })

@PowerMockIgnore("javax.management.*")

Powermockito.mockStatic(StaticClassToMock.class);

Powermockito.when(StaticClassToMock.method(Object.. params)).thenReturn(Object value)

模擬final方法

Final方法的模擬類似於模擬靜態方法。

@RunWith(PowerMockRunner.class)

@PrepareForTest({ FinalClassToMock.class })

@PowerMockIgnore("javax.management.*")

Powermockito.mockStatic(FinalClassToMock.class);

Powermockito.when(StaticClassToMock.method(Object.. params)).thenReturn(Object value)

模擬靜態類

模擬靜態類類似於模擬靜態方法。

使用spy方法避免執行被測類中的成員函數

如被測試類為:TargetClass,想要屏蔽的方法為targetMethod.

1)  PowerMockito.spy(TargetClass.class);

2)  Powemockito.when(TargetClass.targetMethod()).doReturn()

3)  注意加入

@RunWith(PowerMockRunner.class)

@PrepareForTest(DisplayMoRelationBuilder.class)

@PowerMockIgnore("javax.management.*")

參數匹配器

有時我們在處理doMethod(Param param)時,不想進行精確匹配,這時可以使用Mockito提供的模糊匹配方式。

如:

Mockito.anyInt(),Mockito.anyString()

處理public void型的靜態方法

Powermockito.doNothing.when(T class2mock, String method, <T>… params>

3.常見問題

使用Powermock后會提示classloader錯誤

加入注解:

@PowerMockIgnore("javax.management.*")

Eclipse + junit4 + Emma 無法統計覆蓋率情況

Emma問題導致,暫無處理方法。

使用Ant和HUTAF_LLT覆蓋率插件出現的覆蓋率無法統計情況

原因是對被統計類使用了PrepareForTest()注解,去掉該注解,不再進行被測類方法進行mock.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM