最近一直有使用PowerMock进行测试。很方便,但是当待测试方法的调用情况比较复杂的时候,往往不知道怎么处理。在这里把自己的解决方法整理一下做个备份。
直接以问题-解决方法的方式。
1.PowerMock mock 静态方法
mock静态方法,需要提前打上** @RunWith 和@PrepareForTest注解,@PrepareForTest**这个注解可用于类和方法。
关于** @RunWith 和@PrepareForTest**的使用场景,个人理解就是比较复杂的情形,比如mock私有方法,静态方法,mock在方法内部new的对象,final方法。
有了这两个注解,在mock静态方法之前,还需要使用** PowerMockito.mockStatic(YourStaticClass.class);**,之后就可以对该类的静态方法进行mock或者别的操作了。代码如下:
@RunWith(PowerMockRunner.class)
@PrepareForTest(YourStaticClass.class)
public class XXXTest {
@Test
public void test() {
PowerMockito.mockStatic(YourStaticClass.class);
when(YourStaticClass.staticMethod(something)).thenReturn(something);
// 待测试逻辑
}
}
2.PowerMock mock 枚举类的方法
这个的情况是这样子,有个枚举A,如下
public enum NameEnum {
ZHANGSAN("张三") {
@Override
public boolean getName() {
return this.name;
}
};
private String name;
WhiteListEnum(String name) {
this.name = name;
}
public abstract String getName();
}
待测试方法中调用了NameEnum.ZHAGNSAN.getName();,现在要抑制这个方法。做法如下:
@RunWith(PowerMockRunner.class)
@PrepareForTest(
value = {NameEnum.class},
fullyQualifiedNames = {
"com.xx.NameEnum$1"
}
)
public class XXTest {
@Test
public void test() {
// 替换NameEnum.ZHANGSAN的getName方法 这里使用getDeclaredMethods()获取数组,再获取方法,
// 是经过测试,直接使用方法名获取方法,会报NoSuchMethod,才疏学浅,只好这么用
Method getName= NameEnum.ZHANGSAN.getClass().getDeclaredMethods()[0];
// with里面传入一个新的InvocationHandler实现,powermock将会使用这个实现替换原有方法
PowerMockito.replace(getName).with((proxy, method, args) -> "李四");
// 你的测试逻辑
}
}
整个的思路就是将枚举类中的方法替换为新的实现,在**@PrepareForTest注解中,需要指定全限定名,注意$1**,是为了取出枚举的第一个枚举量。
在获取待替换Method的时候, 也可以用PowerMockito的method方法,但是我这种情形,如果使用PowerMockito的method方法,会找到两个getName方法,抛异常。可能是由于枚举的原因,我不清楚,下面的父类调用的情形,可以用这个方式获取Method。
3.PowerMock mock 父类方法调用
我的情况是待测试方法中调用了本类的私有方法,在本类私有方法中调用了父类的公共方法。简单用代码模拟一下
public class Father{
public String getName(){
return "father";
}
}
public class Son extends Fahter{
public void pendingTestMethod(){
………………
getFatherName();
………………
}
private String getFatherName(){
return getName();
}
}
待测试的主要逻辑都在getFatherName()方法中,所以没有直接mock该方法。
那么这种情况,如何mock父类的getName()方法呢,代码如下:
@RunWith(PowerMockRunner.class)
@PrepareForTest(Fahter.class)
public class XXTest{
@Test
public void test() {
// 找到getConfig()方法,替换为自己实现
Method method = PowerMockito.method(Son.class, "getName");
PowerMockito.replace(method).with((proxy, method1, args) -> something);
// 你的测试逻辑
}
}
其实这里的逻辑是和mock枚举类方法一样的,只不过,这里需要注意的是,在反射获取待替换方法的时候(这次我是用的是PowerMockito.method(Son.class, “getName”)),是在子类方法中获取父类的这个方法,这个需要注意一下。
暂时就碰见这三种比较棘手的情况,以后在遇到复杂情况再来加。
有错误的地方欢迎指正
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)