在JMockit中是否有一种方法可以从模拟方法中调用原始方法? [英] Is there a way in JMockit to call the original method from a mocked method?

查看:239
本文介绍了在JMockit中是否有一种方法可以从模拟方法中调用原始方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的模拟类中,我正在模拟方法foo()。对于某些测试用例,我希望foo()的模拟实现返回一个特殊值。对于其他测试用例,我想使用foo()的实际实现。我在我的mock类中定义了一个布尔值,以便我可以在mock方法中确定是否要返回特殊值,或使用real方法。问题是,我似乎无法弄清楚如何从模拟方法中调用真实方法。

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()的真实实现,mock方法将调用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:此外,对于我的大多数测试用例我 NOT 想要模拟实现。所以我最初的尝试是在我需要模拟对象的那些测试用例中只调用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..

这篇关于在JMockit中是否有一种方法可以从模拟方法中调用原始方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆