JMockit 中有没有办法从模拟方法调用原始方法?
在我的模拟类中,我正在模拟方法 foo().对于某些测试用例,我希望 foo() 的模拟实现返回一个特殊值.对于其他测试用例,我想使用 foo() 的真正实现.我在我的模拟类中定义了一个布尔值,以便我可以在模拟方法中确定是要返回特殊值还是使用真实"方法.问题是,我似乎无法弄清楚如何从模拟方法中调用真实方法.
In my mock class, I'm mocking method foo(). For some test cases, I want the mock implementation of foo() to return a special value. For other test cases, I want to use the real implementation of foo(). I have a boolean defined in my mock class so that I can determine in the mock method whether I want to return the special value, or use the "real" method. The problem is, I can't seem to figure out how to call the real method from the mocked method.
我发现您可以在名为it"的模拟对象中定义一个特殊成员(具有被模拟对象的类型).这允许您从模拟实现中引用真实的类.所以,我的计划是,如果我需要调用 foo() 的真实"实现,模拟方法将调用 it.foo().但是,这不起作用,因为调用 it.foo() 只是再次调用模拟版本,而不是真实版本,所以我最终得到了无限递归.
I found that you can define a special member within the mock object named "it" (with type of the object being mocked). This allows you to reference the real class from the mock implementation. So, my plan was, if I needed to invoke the "real" implementation of foo(), the mock method would call it.foo(). However, this doesn't work, because calling it.foo() just calls the mock version again, not the real version, so I end up with infinite recursion.
有什么办法可以让这个工作吗?
Is there some way to make this work?
使用代码示例可能会更清楚,这是我当前的模拟方法实现的样子:
it might be clearer with a code example, here's what my current mocked method implementation looks like:
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 中执行此操作......当我尝试这样做时,我的模拟实现从未被调用.
EDIT 2: Also, for most of my test cases I do NOT want the mock implementation. So my initial attempt at this was to only call Mockit.redefineMethods() within those test cases where I needed the mock object. But this didn't work - it seems you can only do this within setup/teardown ... my mock implementation never got called when I tried that.
解决方案说明:
起初我不认为给出的答案有效,但在玩了一些之后,问题似乎是我将 JMockit 核心"方法与注释"驱动方法混合在一起.显然,在使用注释时,您需要使用 Mockit.setupMocks,而不是 Mockit.redefineMethods().这就是最终奏效的方法:
At first I didn't think the answer given worked, but after playing with it some more, it seems the problem is that I was mixing JMockit "core" methods with the "annotation" driven methods. Apparently when using the annotation you need to use Mockit.setupMocks, not Mockit.redefineMethods(). This is what finally worked:
@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();
}
}
}
推荐答案
我认为你可以使用 @Mock
注释来做到这一点.从文档中,您的模拟类上的 @Mock(reentrant=true)
应该这样做.
I think you can do this with the @Mock
annotation. From the docs, @Mock(reentrant=true)
on your mock class should do it.
请参阅 http://jmockit.googlecode.com/svn/trunk/www/javadoc/mockit/Mock.html
例如看这里 http://jmockit.googlecode.com/svn/trunk/www/tutorial/StateBasedTesting.html#reentrant
不过我还没有测试过..
I haven't tested this though..
相关文章