在我的模拟类中,我正在模拟方法foo()。对于某些测试用例,我希望foo()的模拟实现返回一个特殊值。对于其他测试用例,我想使用foo()的真实实现。我在我的模拟类中定义了一个布尔变量,以便在模拟方法中确定我是否要返回特殊值或使用“真实”方法。问题是,我似乎无法弄清楚如何从模拟方法调用真实方法。
我发现您可以在模拟对象中定义一个名为“it”的特殊成员(类型为被模拟的对象)。这使您可以从模拟实现中引用真实类。因此,我的计划是,如果我需要调用foo()的“真实”实现,则模拟方法将调用it.foo()。然而,这并不起作用,因为调用it.foo()只会再次调用模拟版本,而不是真实版本,因此我最终得到无限递归。
有没有办法让这个工作?
编辑:通过代码示例可能更清楚,这是我的当前模拟方法实现:
EDIT 2: 另外,对于大多数测试用例,我不想要模拟实现。因此,我的初始尝试是仅在需要模拟对象的测试用例中调用Mockit.redefineMethods()。但这并不起作用 - 当我尝试时,似乎只能在设置/拆卸中这样做...我的模拟实现从未被调用。
解决方案注释:
起初,我认为给出的答案没有起作用,但在进一步尝试后,问题似乎是我混合使用了JMockit“核心”方法和“注释”驱动方法。显然,在使用注释时,您需要使用Mockit.setupMocks而不是Mockit.redefineMethods()。这就是最终起作用的内容:
然后,针对模拟课程:
我发现您可以在模拟对象中定义一个名为“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();
}
}
EDIT 2: 另外,对于大多数测试用例,我不想要模拟实现。因此,我的初始尝试是仅在需要模拟对象的测试用例中调用Mockit.redefineMethods()。但这并不起作用 - 当我尝试时,似乎只能在设置/拆卸中这样做...我的模拟实现从未被调用。
解决方案注释:
起初,我认为给出的答案没有起作用,但在进一步尝试后,问题似乎是我混合使用了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();
}
}
}