在我的模拟类中,我正在模拟方法 foo()。对于某些测试用例,我希望 foo() 的模拟实现返回一个特殊值。对于其他测试用例,我想使用 foo() 的真正实现。我在我的模拟类中定义了一个布尔值,以便我可以在模拟方法中确定是要返回特殊值还是使用“真实”方法。问题是,我似乎无法弄清楚如何从模拟方法中调用真正的方法。
我发现您可以在名为“it”的模拟对象中定义一个特殊成员(具有被模拟对象的类型)。这允许您从模拟实现中引用真实的类。所以,我的计划是,如果我需要调用 foo() 的“真实”实现,模拟方法将调用 it.foo()。但是,这不起作用,因为调用 it.foo() 只是再次调用模拟版本,而不是真实版本,所以我最终得到了无限递归。
有什么办法可以使这项工作?
编辑:使用代码示例可能会更清楚,这是我当前的模拟方法实现的样子:
private RealClass it;
...
public SomeClass foo() {
if(fakeIt) {
return new SomeClass("fakevalue");
} else {
// doesn't work, just keeps calling the mock foo
// in infinite recursion
return it.foo();
}
}
编辑 2:另外,对于我的大多数测试用例,我不想要模拟实现。所以我最初的尝试是只在我需要模拟对象的那些测试用例中调用 Mockit.redefineMethods() 。但这不起作用 - 似乎你只能在 setup/teardown 中做到这一点......当我尝试这样做时,我的模拟实现从未被调用过。
解决方案注意事项:
起初我不认为给出的答案有效,但在玩了一些之后,似乎问题在于我将 JMockit “核心”方法与“注释”驱动方法混合在一起。显然,在使用注释时,您需要使用 Mockit.setupMocks,而不是 Mockit.redefineMethods()。这就是最终奏效的方法:
@Before
public void setUp() throws Exception
{
Mockit.setUpMocks(MyMockClass.class);
}
然后,对于模拟类:
@MockClass(realClass = RealClass.class)
public static class MyMockClass {
private static boolean fakeIt = false;
private RealClass it;
@Mock(reentrant = true)
public SomeClass foo() {
if(fakeIt) {
return new SomeClass("fakevalue");
} else {
return it.foo();
}
}
}