PowerMockito.mockStatic(class) 模拟静态方法调用
为什么要写单元测试
- 给我们重构的信心(give us the confidence to refactor)。一堆纠缠而无测试的代码你敢随便修改?
- 好的单元测试就是文档 (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
@Slf4jpublicclassSysDataCodeUtils{publicstatic StringgetNameByCodeAndValue(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})publicclassShareProfitRefundSettleServiceImplTest{@InjectMocks
ShareProfitRefundSettleServiceImpl shareProfitRefundSettleService=newShareProfitRefundSettleServiceImpl();@Mock
ClearingDao clearingDao;@Beforepublicvoidbefore(){
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。