PowerMockito.mockStatic(class) 模擬靜態方法調用

PowerMockito.mockStatic(class) 模擬靜態方法調用

爲什麼要寫單元測試

  1. 給我們重構的信心(give us the confidence to refactor)。一堆糾纏而無測試的代碼你敢隨便修改?
  2. 好的單元測試就是文檔 (documenting expected behavior)。幾個實用的例子比文檔讓人感興趣的多!

引入依賴

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>2.23.4</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito2</artifactId>
            <version>2.0.0</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>2.0.0</version>
            <scope>test</scope>
        </dependency>

模擬工具類調用靜態方法

工具類:SysDataCodeUtils

@Slf4j
public class SysDataCodeUtils {
    public static String getNameByCodeAndValue(String code, String key) {
        try {
            List<SysDataCodeDTO> list = sysDataCodeService.getListByCode(code);
            for (SysDataCodeDTO dataCodeDTO : list) {
                if (dataCodeDTO.getCode().equals(key)) {
                    return dataCodeDTO.getValue();
                }
            }
        } catch (Exception e) {
            log.error("獲取快速編碼表異常:{}", e);
        }
        return StrUtil.EMPTY;
    }
}

測試類:ShareProfitRefundSettleServiceImplTest

@RunWith(PowerMockRunner.class)
@PrepareForTest({ SysDataCodeUtils.class })
public class ShareProfitRefundSettleServiceImplTest {

    @InjectMocks
    ShareProfitRefundSettleServiceImpl shareProfitRefundSettleService = new ShareProfitRefundSettleServiceImpl();

    @Mock
    ClearingDao clearingDao;

    @Before
    public void before(){
        log.info("start--------{}",this.getClass().getName());
        
        PowerMockito.mockStatic(SysDataCodeUtils.class);
        PowerMockito.when(SysDataCodeUtils.getNameByCodeAndValue("SHARE_PROFIT_REFUND_TERM", "SWITCH")).thenReturn("OPEN");
        
    }
}

註解說明

@RunWith(MockitoJUnitRunner.class):JUnit 使用 Mockito 模擬框架提供的“單元測試運行器。

@RunWith(PowerMockRunner.class):JUnit 使用 PowerMock 框架中的單元測試運行器。
(使用這些特定於框架的測試運行程序的要點是,它們負責使用特殊的特定於框架的註釋初始化所有字段)。

因此,這裏的區別僅在於:第一個示例是使用 Mockito 框架編寫的,第二個示例是使用 PowerMock
編寫的。*如果要模擬對靜態方法的調用,需要使用 @RunWith(PowerMockRunner.class)。如果不需要模擬靜態或私有函數,最好還是使用原生 MockitoJUnitRunner 進行單測。

@PrepareForTest({ SysDataCodeUtils.class }):當使用PowerMockito.whenNew方法時,必須加註解@PrepareForTest和@RunWith。註解@PrepareForTest裏寫的類是需要mock的new對象代碼所在的類。如果有兩個不同類的靜態方法需要驗證呢,比如類A、類B,則只需要一起添加,用逗號隔開就可以了:@PrepareForTest({ A.class, B.class })。

@InjectMocks:創建一個實例,簡單的說是這個Mock可以調用真實代碼的方法,其餘用@Mock(或@Spy)註解創建的mock將被注入到用該實例中。

@Mock: 創建一個Mock。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章