这是场景,我在类的一种方法 myClass
中有类似的东西public class MyClass{
public Object build(Map map) {
BaseClass cls;
if(SomeconditionTrue) {
cls = new ChildClass1(new ABC());
} else {
cls = new ChildClass2(new ABC());
}
cls.callMethod();
}
}
对于上述情况,我正在使用PowerMockito编写一个测试案例,我想模拟此方法调用cls.callMethod()
。当我试图模拟时,它将调用正在失败的实际方法callMethod()
。某些身体可以帮助我嘲笑该方法吗?尝试使用PowerMockito PowerMockito.stub和其他一些选项使用几个方案,但它始终调用实际方法。模拟此方法的原因是,它具有不同的逻辑,并且可以调用不同的API,该方法非常复杂,因此我们需要模拟此方法。
您可以为此转向PowerMock,但这不一定是此类问题的"最佳"答案。
从本质上讲,您在代码中调用 new 的事实给您带来了悲伤 - 您通过此创建了难以测试的代码。您可能会观看这些视频以了解我在说什么。
长话短说:而不是转向大型PowerMock锤子,而是可以重新编写代码;使用依赖项注入。因此,您正在测试的类无需创建这些对象本身,而是可以使用某些工厂对象来提供所需的对象。然后,您可以使用任何"普通"模拟框架,例如Easymock或Mockito来创建该工厂的模拟版本。
编辑:我认为您可能已经过度复杂了整个问题。您会发现,有一个基础课或两个孩子课,这并不重要。事实是:对于每种测试方法,您应该准确地了解将采取哪些路径。您要么想要创建了孩子1,要么是一个孩子。因此,我为您创建了一个简化的解决方案:
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
因此,您可以看到 - 基础上没有什么叫;仅仅因为该子对象被"完全"嘲笑。
全部是:您正在测试的代码仅需要一个某个类型的对象;而且您事先知道这是Child1还是Child2。因此,您只需为该类创建模拟即并使用powermockito来返回模拟您刚创建的。
记录:我与间谍一起玩了一段时间;但是他们在这里没有帮助。而且它们也不需要!