开发工具: IDEA
语言 java
转载
背景
Mockito无法实现对静态函数、构造函数、私有函数、Final 等函数的模拟。 使用powermock进行可以模拟静态方法,删除静态初始化程序,允许模拟而不依赖注入等等
原理:
Mockito使用继承的方式实现mock的,用CGLIB生成mock对象代替真实的对象进行执行,为了mock实例的方法,可以在subclass中覆盖它,而static方法是不能被子类覆盖的,所以Mockito不能mock静态方法。 PowerMock通过在执行测试时在运行时修改字节代码来完成这些技巧。
步骤
第一步:maven依赖
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.6</version>
<scope>compile</scope>
</dependency>
第二步 测试类代码
class 文件前面必须加入 @RunWith和@PrepareForTest
@RunWith(PowerMockRunner.class)
@PrepareForTest({JwtUtils.class})
public class AbnormalDataServiceImplTest {}
如果想要对某个类的静态方法进行mock,则必须在PrepareForTest后面加上相应的类名 在对该类的某个方法进行mock之前,还必须先对整个类进行mock:
@Before
public void setUp() throws Exception {
PowerMockito.mockStatic(JwtUtils.class);
}
在测试方法中,我们对静态的方法进行了mock:
PowerMockito.when(JwtUtils.getCurrentOrgId()).thenReturn(1l);
测试成功
问题
1、# springboot2.x 单元测试 mockito powermock 兼容性问题
在使用springboot做单元测试的时候,发现依赖的mockito已经是2.x了,然后powermock虽然对应有一个api,但是并不能真正的支持,遇到了一系列的兼容问题,最后解决的版本如下
问题解决方法参考与: blog.csdn.net/u013076044/…
2、PowerMockito.when()参数问题
在使用 PowerMockito.when()的时候,参数必须都是mock的,
例如在JsonUtils.toListCommonResponse(body, TeamDTO.class);这句中,
public static <T> CommonResponse<List<T>> toListCommonResponse(String json, Class<T> clazz)
toListCommonResponse需要的是一个string类型和class类型的参数进行mock
单纯使用PowerMockito.when(JsonUtils.toListCommonResponse(any(), any(TeamDTO.class))).thenReturn(listCommonResponse);这句会报错
需要把TeamDTO.class->Class.class PowerMokito才会编译通过
3、PowerMockito @value
在Test中
举例:
PowerMock基本用法
(1) 普通Mock:Mock参数传递的对象
说明:普通Mock不需要加@RunWith和@PrepareForTest注解。
(2) Mock方法内部new出来的对象
说明:当使用PowerMockito.whenNew方法时,必须加注解@PrepareForTest和@RunWith。注解@PrepareForTest里写的类是需要mock的new对象代码所在的类。
(3) Mock普通对象的final方法
说明: 当需要mock final方法的时候,必须加注解@PrepareForTest和@RunWith。注解@PrepareForTest里写的类是final方法所在的类。
(4) Mock普通类的静态方法
说明:当需要mock静态方法的时候,必须加注解@PrepareForTest和@RunWith。注解@PrepareForTest里写的类是静态方法所在的类。
(5) Mock私有方法
说明:和Mock普通方法一样,只是需要加注解@PrepareForTest(ClassUnderTest.class),注解里写的类是私有方法所在的类。
(6) Mock系统类的静态和final方法
说明:和Mock普通对象的静态方法、final方法一样,只不过注解@PrepareForTest里写的类不一样 ,注解里写的类是需要调用系统方法所在的类。
(7) Mock protected方法
说明:Mock受保护(protected)的方法时,注解@PrepareForTest里写的类是该方法所在的类,如果存在子类继承父类的该方法时,则@PrepareForTest里写的是子类信息。