JMockit 基础:模拟对象、模拟参数、期望

Posted

技术标签:

【中文标题】JMockit 基础:模拟对象、模拟参数、期望【英文标题】:JMockit basics: mocked object, mocked parameter, expectation 【发布时间】:2014-09-17 16:39:29 【问题描述】:

我刚开始使用 JMockit,我对 JMockit 的一些基础知识有些困惑,比如创建模拟对象的时间、模拟对象范围以及模拟的效果等。请帮助解决以下问题。

我的问题参考以下代码:

public class MyClassTest

    @Mocked("method1","method2")
    ClassA classA;  //ClassA has only static method

    @Mocked
    ClassB classB;

    @Test
    public void test1()
    
        new NonStrictExpectations() 
            MyClassA.method3(classB);
            result = xxx;
        ;

        // testing code
        ....

        // verification
        ...
    

    @Test
    public void test2(@Mocked ClassC classC)
    
        ...
    

问题:

    关于声明为 junit 测试的实例变量的 @Mocked,例如 @Mocked ClassB classB:

(1) 对于 junit,实例变量是为每个测试新创建的(如 test1()、test2()),对吧?是不是在每次测试运行之前,都会创建一个新的 ClassB 模拟实例?

(2) 它模拟类。它使 ClassB 中的所有方法都针对所有测试(在本例中为 test1() 和 test2())进行模拟,对吗?

(3) 如果为mocked对象指定了方法,如"@Mocked("method1","method2") ClassA classA;",是不是只有method1和method2可以mock?是否可以在 Expectations 中添加其他方法来模拟测试?

    关于传入测试的@Mocked 参数,例如test2 的“@Mocked ClassC classC”:

我认为这个模拟不应该影响其他测试? ClassC 是不是只在 test2() 中 mock 过?

    期望:

(1) 对于测试中指定的期望,它的作用域是否在测试本地,意味着模拟方法仅在该测试中有效?比如ClassA.method3()只在test1()中被mock了,对吧?

(2) 期望中记录的方法只有在测试代码中调用匹配方法时才会运行,是吗?如果记录的方法参数不匹配,会运行真正的方法吗?

运行 test1() 时,我在 ClassA.method3() 中遇到异常。不知何故, ClassA.method3() 的真实方法被执行并给出了异常。我猜是因为 ClassA.method3() 的参数不匹配?

【问题讨论】:

对不起格式。它不容易阅读。看来我需要添加一些换行符。 【参考方案1】:

回答您的问题:

    (1) 是; (2) 是; (3) 是的,在同一个测试类中不能mock其他方法。

    可以,只在有mock参数的测试中。

    (1) 对,期望只在记录的范围内有效。 (2) 不,一旦被模拟,一个方法的真正实现就永远不会执行。

至于你得到的异常,如果没有完整的测试,我不知道为什么会发生。

【讨论】:

非常感谢!我得到了异常,因为我试图模拟一个未包含在声明列表中的方法。这与我对问题1(3)的错误理解有关。正如您所提到的,其他方法不能在同一个测试类中模拟(虽然我认为我可以稍后添加模拟更多方法)。由于该方法不能被模拟,所以它执行了真正的方法并给出了异常。

以上是关于JMockit 基础:模拟对象、模拟参数、期望的主要内容,如果未能解决你的问题,请参考以下文章

JMockit - 期望和静态方法

如何使用Jmockit模拟JdbcTemplate.update?

用jmockit模拟扩展类的抽象方法

如何从 Jmockit 中的模拟方法返回不同的值?

JMockit MockUp 可以模拟 toString() 吗?

JMockit 模拟返回 String 而不是提供的 List<String>