有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用@Mock注释的java对象应该设置为详细值吗?

我是莫基托的新手,我有一个问题。假设我尝试在测试方法中使用一个对象实例。我知道我可以使用@Mock来实现它,这是因为我们试图将测试与该对象方法隔离开来。然而,为了控制测试分支,我确实需要在这个对象中设置一些值。我应该仍然使用Mock还是简单地使用新的Object()方式来实例化它?还是没关系(每种方式都很好)

谢谢


共 (1) 个答案

  1. # 1 楼答案

    让我们看看,好吗

    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 = static const

    const = private const

    protected = null

    package = null

    updated = but now

    一些想法:

    显然,static const确实是您所期望的(我使用mocked.STATIC_CONST来获取值,但是,它是静态的,所以值不是来自mocked,而是来自从头开始的类定义)

    有点令人惊讶,至少对我来说,分配模拟对象的字段实际上是有效的。但请注意:原始类中的作业仅对final字段有效。换言之:Mockito得到了正确的答案,但不是针对非最终字段

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

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

    除此之外:当你模拟一个对象时,你绝对不应该以任何方式处理该模拟的字段。你看:所有的方法都在那个模拟上。。。它们与您的类中的原始源代码无关。它们只是:可以使用相应的Mockito方法配置/验证的空shell。让我们了解一下:模拟对象中字段的实际内容无关紧要:因为通常处理这些字段的方法。。。“不存在”

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

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