应该使用@Mock注释设置Object的详细值吗?

时间:2018-12-07 02:13:53

标签: java junit mockito powermock

我是Mockito的新手,我有一个问题。假设我尝试在测试方法中包含一个对象实例。我知道我可以使用@Mock来拥有它,这是因为我们试图将测试与该Object方法隔离。但是,要控制测试分支,我确实需要在此对象中设置一些值。我应该还是使用Mock还是应该简单地使用新的Object()实例化它?还是没关系(每种方法都可以)?

谢谢。

1 个答案:

答案 0 :(得分:2)

让我们找出答案吧!!

import org.mockito.Mockito;

class Scratch {  
    public final static String STATIC_CONST = "static const";
    private final String JUST_CONST = "private const";
    protected String protectedField = "protected field";
    String packageProtectedField = null;

    public static void main(String[] args) {
        Scratch mocked = Mockito.mock(Scratch.class);
        System.out.println("static    = " + mocked.STATIC_CONST);
        System.out.println("const     = " + mocked.JUST_CONST);
        System.out.println("protected = " + mocked.protectedField);
        System.out.println("package   = " + mocked.packageProtectedField);

        mocked.packageProtectedField = "but now";
        System.out.println("updated  = " + mocked.packageProtectedField);
    }
}

上面的照片:

  

static =静态常量

     

const =私有常量

     

protected = null

     

package = null

     

updated =但现在

一些想法:

很显然,static const确实是您所期望的(我使用mocked.STATIC_CONST来获取值,但是,它是静态的,因此该值并非来自mocked但还是从Scratch类定义开始)。

令人惊讶的是,至少对我来说,模拟对象的分配字段确实有效。但请注意:原始类中的赋值仅对该final字段有效。换句话说:Mockito正确地做到了这一点,但不适用于非最终领域。

更令人惊讶的是,人们可以将值存储到模拟中...

但是,老实说,这些都不重要。您会发现,在合理的设计中,您的所有可变字段首先应该是私有。可变状态代表了对象的绝对核心。 外部代码绝对不能处理这些!换句话说:理想情况下,即使您的测试也不关心对象的内部状态(在非常罕见的情况下,使用包保护的getter方法访问内部状态以简化验证可能是有意义的,但这应该是罕见的例外)。

除此之外:模拟对象时,您绝对不应以任何方式处理该模拟对象的字段。您会看到:该模拟程序上的所有方法 ...它们与类中的原始源代码无关。它们就是:空的shell,您可以使用相应的Mockito方法进行配置/验证。让它陷入:模拟对象中字段的实际内容无关紧要:因为通常用于处理这些字段的方法……“不存在”!

因此,长话短说:如图所示,模拟对象可以携带状态。但正如所解释的:您应该完全忽略该方面。使用模拟的唯一正确方法是在模拟上指定/验证方法调用。

最后:我希望EasyMock,PowerMock(ito)的行为类似。另一方面,当其他模拟框架实际上表现稍有不同时,我也不会感到惊讶。我只对Mockito进行了测试,因为,恕我直言,在2018年,Mockito是为JVM编写单元测试时应该使用的唯一的模拟框架。