我有以下代码:
public class MyClass() {
private MyObject myObject = getMyObject();
public MyObject getMyObject() {
if (myObject == null) {
myObject = MyStaticClass.createMyObject();
}
return myObject;
}
// heaps more methods
}
public class MyTest() {
private MyClass spyMyClass = spy(new MyClass());
public MyTest() {
doReturn(null).when(spyMyClass).getMyObject();
}
@Test
public void someTest() {
ClassUnderTest c = new ClassUnderTest();
assertTrue(c.someMethod(spyMyClass));
}
}Could not initialise class MyStaticClass错误导致测试失败。原因是这个静态类初始化了更多在测试期间不可用的类对象(例如数据库),我不在乎,因为您可以在调用getMyObject()方法时返回null。
但是这个意图也失败了,因为在到达doReturn(null)行之前,测试已经在spy(new MyClass())行失败了,在该行中,它调用getMyObject()来初始化私有成员myObject。
解决上述情况的方法是使用mock(MyClass.class)而不是spy(new MyClass()),这样私有成员myObject就不会被初始化,因此不会调用真正的getMyObject()方法。
但是,这个解决方法给我带来了另一个麻烦,因为这意味着我必须为MyClass中的那些堆更多的方法做一些配置(甚至只是对MyClass)。
问:是否还有另一种解决方案,我仍然可以在MyClass的实例上使用间谍,这样我就可以忘记在该类中配置这些堆--更多的方法,但是我可以绕过Could not initialise class MyStaticClass错误?
我不能简单地使用Power来模拟MyStaticClass,因为我已经为MyTest使用了另一个测试运行程序。除非您的答案能够说明同时运行两个测试运行程序是多么容易,而不实现一个新的混合测试运行程序。
多亏了Adam,我现在有了一个很好的工作代码:
public class MyTest() {
private MyClass spyMyClass = spy(new MyClass() {
@Override
public MyObject getMyObject() {
return null;
}
});
@Test
public void someTest() {
ClassUnderTest c = new ClassUnderTest();
assertTrue(c.someMethod(spyMyClass));
}
}发布于 2017-10-04 02:22:34
创建MyClass的子类并在private MyClass spyMyClass = spy(new TestMyClass());中使用它
class TestMyClass extends MyClass {
@Override // fortunately, the original method called in constructor can be overridden (what could be considered bad)
public MyObject getMyObject() {
// something that does not fail the constructor
}
}通常,这是问题的潜在原因,因为您在构造函数中调用一个非私有的、非最终的方法。对于测试用例,这可能是可以接受的。
稍微回避一下,我想看看这个MyClass对象的责任是明智的。它是不是做得太多了,所以很难测试和交互?这通常会导致“难以模仿”综合症。
https://stackoverflow.com/questions/46555797
复制相似问题