【发布时间】:2020-05-09 03:50:46
【问题描述】:
有什么方法可以使用Mockito 或PowerMockito 来拦截对对象的非静态方法的调用,或者至少是对单例对象的调用?
以下类提供了一个示例:
public class Singleton {
private static Singleton INSTANCE = null;
private Singleton(Object parameter) {}
public static Singleton getInstance(Object parameter) {
if (INSTANCE == null) {
INSTANCE = new Singleton(parameter);
}
return INSTANCE;
}
public String process(String a, String b) {
return (a + b);
}
// Other methods
}
public class Foreign {
private Foreign() {}
public static void main(String[] args) {
System.out.println(Singleton.getInstance(new Object()).process("alpha", "beta"));
}
}
Singleton 对象是在 Foreign 类中创建的,不受某些测试代码的控制(上面未显示)。这两个类都不能修改。目的是拦截测试代码中对非静态process() 方法的调用,以便对于某些值返回不同的结果,例如通话
Singleton.getInstance(new Object()).process("alpha", "beta");
模拟返回 "alpha-beta" 而不是预期的 "alphabeta"。
一种解决方案可能是拦截 Singleton.getInstance() 方法来实例化 Singleton 的自定义子类,例如使用
public class SubSingleton extends Singleton {
public SubSingleton(Object parameter) {
super(parameter);
}
public String process(String a, String b) {
if ("alpha".equals(a) && "beta".equals(b)) {
return a + "-" + b;
}
return super.process(a + b);
}
}
然后,对Singleton.process() 方法的调用将被拦截,如下所示:
Object parameter = new Object();
PowerMockito.doReturn(new SubSingleton(parameter)).when(Singleton.class, "getInstance", parameter);
但是,上面的Singleton类只提供了一个私有构造函数,所以不能扩展。使用PowerMockito.whenNew() 返回部分模拟(间谍)也将不起作用,因为Singleton 类不提供无参数构造函数。
可以通过任何其他方式实现所需的模拟吗?可以对非单例类进行吗?
【问题讨论】:
标签: java mocking mockito powermockito intercept