使用PowerMockRunner和Mockito編寫單元測試用例詳解


單元測試可以提高測試開發的效率,減少代碼錯誤率,提高代碼健壯性,提高代碼質量。在Spring框架中常用的兩種測試框架:PowerMockRunner和SpringRunner兩個單元測試,鑒於SpringRunner啟動的一系列依賴和數據連接的問題,推薦使用PowerMockRunner,這樣能有效的提高測試的效率,並且其提供的API能覆蓋的場景廣泛,使用方便,可謂是Java單元測試之模擬利器。

1. PowerMock是什么?

PowerMock是一個Java模擬框架,可用於解決通常認為很難甚至無法測試的測試問題。使用PowerMock,可以模擬靜態方法,刪除靜態初始化程序,允許模擬而不依賴於注入,等等。PowerMock通過在執行測試時在運行時修改字節碼來完成這些技巧。PowerMock還包含一些實用程序,可讓您更輕松地訪問對象的內部狀態。

舉個例子,你在使用Junit進行單元測試時,並不想讓測試數據進入數據庫,怎么辦?這個時候就可以使用PowerMock,攔截數據庫操作,並模擬返回參數。

2. PowerMock包引入

<!-- 單元測試 依賴-->
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-core</artifactId>
            <version>2.0.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>2.23.0</version>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>2.0.4</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito2</artifactId>
            <version>2.0.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.github.jsonzou</groupId>
            <artifactId>jmockdata</artifactId>
            <version>4.3.0</version>
        </dependency>
        <!-- 單元測試 依賴-->

3. 重要注解說明

@RunWith(PowerMockRunner.class) // 告訴JUnit使用PowerMockRunner進行測試
@PrepareForTest({RandomUtil.class}) // 所有需要測試的類列在此處,適用於模擬final類或有final, private, static, native方法的類
@PowerMockIgnore("javax.management.*") //為了解決使用powermock后,提示classloader錯誤

4. 使用示例

4.1 模擬接口返回

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

InterfaceToMock mock = Powermockito.mock(InterfaceToMock.class)

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

Powermockito.when(mock.method(Params..)).thenThrow(Exception)
4.2 設置對象的private屬性

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

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

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

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

4.3 模擬構造函數

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

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

@RunWith(PowerMockRunner.class)

@PrepareForTest({ InstanceClass.class })

@PowerMockIgnore("javax.management.\*")

Powermockito.whenNew(InstanceClass.class).thenReturn(Object value)
4.4 模擬靜態方法

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

@RunWith(PowerMockRunner.class)

@PrepareForTest({ StaticClassToMock.class })

@PowerMockIgnore("javax.management.\*")

Powermockito.mockStatic(StaticClassToMock.class);

Powermockito.when(StaticClassToMock.method(Object.. params)).thenReturn(Object value)
4.5 模擬final方法

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

@RunWith(PowerMockRunner.class)

@PrepareForTest({ FinalClassToMock.class })

@PowerMockIgnore("javax.management.\*")

Powermockito.mockStatic(FinalClassToMock.class);

Powermockito.when(StaticClassToMock.method(Object.. params)).thenReturn(Object value)
4.6 模擬靜態類

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

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

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

1) PowerMockito.spy(TargetClass.class);

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

3) 注意加入

@RunWith(PowerMockRunner.class)

@PrepareForTest(DisplayMoRelationBuilder.class)

@PowerMockIgnore("javax.management.*")
4.8 參數匹配器

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

如:Mockito.anyInt(),Mockito.anyString()

4.9 處理public void型的靜態方法
Powermockito.doNothing.when(T class2mock, String method, <T>… params>

5. 單元測試用例可選清單

輸入數據驗證:這些檢查通常可以對輸入到應用程序系統中的數據采用。

  • 必傳項測試
  • 唯一字段值測試
  • 空值測試
  • 字段只接受允許的字符
  • 負值測試
  • 字段限於字段長度規范
  • 不可能的值
  • 垃圾值測試
  • 檢查字段之間的依賴性
  • 等效類划分和邊界條件測試
  • 錯誤和異常處理測試


免責聲明!

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



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