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。

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