你可以为此转向Powermock,但这并不一定是这种问题的“最佳”答案。
从本质上讲,您在代码中调用新的这一事实给您带来了悲伤 - 您创建了难以测试的代码。你可以看这些videos来理解我在说什么。长话短说:不是转向Powermock大锤子,而是反过来重做你的代码;使用依赖注入。所以,不要自己创建这些对象,你的类可以使用一些工厂对象来提供它需要的对象。然后,您可以使用任何“普通”模拟框架(如EasyMock或Mockito)来创建该工厂的模拟版本。
编辑:我想你可能已经过度复杂的整个问题。你看,有一个基类或两个子类并不重要。事情是:对于您的每种测试方法,您都应该准确理解将采用哪条路径。您要么想要创建child1或孩子。因此,我为您建立一个简化的解决方案:
package ghostcat.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
class Abc {}
abstract class Base {
void callMethod() {
System.out.println("Base::callMethod");
}
}
class ChildClass1 extends Base {
ChildClass1(Abc abc) {}
}
class MyClass {
public Object build() {
System.out.println("build1");
Base cls = new ChildClass1(new Abc());
System.out.println("build2");
cls.callMethod();
System.out.println("build3");
return null;
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class)
public class MockNewTest {
@Test
public void test() throws Exception {
ChildClass1 mock = Mockito.mock(ChildClass1.class);
PowerMockito.whenNew(ChildClass1.class).withArguments(Mockito.any(Abc.class)).thenReturn(mock);
new MyClass().build();
}
}
打印:
build1
build2
build3
所以你可以看到 - 没有在基地被调用;只是因为那个孩子的对象被“完全”嘲笑了。
整点是:您的在测代码只需要一个某一类型的对象;而且您事先知道这是孩子1还是孩子2。因此,您只需为该课程创建一个模拟;并使用PowerMockito按顺序返回即模拟你刚刚创建的。
备案:我和间谍玩了一段时间;但他们在这里没有帮助;而且它们也不是必需的!
感谢您的回复。是的,我们可以选择一些工厂模式,但我写的测试用例是针对遗留代码的,我们不想触摸现有的代码。除了更改现有代码之外,是否还有其他选择? – user2334926
@ user2334926我更新了我的答案;拉了一个**为我工作的完整**例子。 – GhostCat