简体   繁体   English

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

[英]Should Object using @Mock annotation be set detailed value?

I am new to Mockito and I have a question. 我是Mockito的新手,我有一个问题。 Let's say I try to have an object instance in my testing method. 假设我尝试在测试方法中包含一个对象实例。 I know I can use @Mock to have it and that's because we try to isolate the testing from that Object methods. 我知道我可以使用@Mock拥有它,这是因为我们试图将测试与该Object方法隔离开。 However, to control the testing branch, I do need to set some values in this object. 但是,要控制测试分支,我确实需要在此对象中设置一些值。 Should I still use Mock or I should simply use new Object() way to instantiate it? 我应该仍然使用Mock还是应该仅使用new Object()实例化它? Or does it not matter (each way is fine)? 还是没关系(每种方法都可以)?

Thanks. 谢谢。

Let's find out, shall we?! 让我们找出答案,对吧?

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);
    }
}

The above prints: 上面的照片:

static = static const 静态=静态const

const = private const const =私有常量

protected = null 保护=空

package = null 包=空

updated = but now 更新=但现在

Some thoughts: 一些想法:

Obviously, the static const is really what you would expect (I used mocked.STATIC_CONST to get the value, but hey, it is static, so the value doesn't come from mocked but from the Scratch class definition anyway). 显然, static const确实是您所期望的(我使用mocked.STATIC_CONST来获取值,但是,嘿,它是静态的,因此该值不是来自于mocked而是来自于Scratch类定义)。

A bit surprising, at least for me is that assigning fields of a mocked object actually works. 至少对于我而言,有点令人惊讶的是, 分配模拟对象的字段实际上是有效的。 But please note: assignments in the original class are only effective for that final field. 但请注意:原始课程中的作业仅对final领域有效。 In other words: Mockito gets that one right, but not for non-final fields. 换句话说:Mockito正确地做到了这一点,但不适用于非最终领域。

Even more surprisingly, one can store values into the mock... 更令人惊讶的是,人们可以将值存储到模拟中。

But honestly, nothing of that really matters. 但老实说,这些都不重要。 You see, in a sound design, all your mutable fields should be private in the very first place. 您会发现,在合理的设计中,所有可变字段首先都应该是私有的。 That mutable state represents the absolute core of your objects. 可变状态代表了对象的绝对核心。 No outside code should ever deal with those! 没有任何外部代码可以处理这些问题! In other words: ideally, even your tests do not care about the internal state of your objects (in very rare situations, it might make sense to have a package protected getter method to access internal state for ease of verification, but that should be a rare exception). 换句话说:理想情况下,即使您的测试也不关心对象的内部状态(在非常罕见的情况下,使用包保护的getter方法访问内部状态以简化验证可能是有意义的,但这应该是罕见的例外)。

Beyond that: when you mock an object, you absolutely should not be dealing in any ways with fields of that mock. 除此之外:模拟对象时, 绝对不应以任何方式处理该模拟对象的字段 You see: all the methods on that mock ... they have nothing to do with the original source code in your class. 您会看到:该模拟上的所有方法 ...与类中的原始源代码无关。 They are just that: empty shells that you can configure/verify using the corresponding Mockito methods. 它们就是:空的shell,您可以使用相应的Mockito方法进行配置/验证。 Let that sink in: the actual content of fields in a mocked object can't matter: because the methods that would normally deal with these fields ... "are not there"! 让它陷入:模拟对象中字段的实际内容无关紧要:因为通常用于处理这些字段的方法……“不存在”!

So, long story short: as shown, mocked objects can carry state. 因此,长话短说:如图所示,模拟对象可以携带状态。 But as explained: you should ignore that aspect completely. 但正如所解释的:您应该完全忽略该方面。 The only correct way to use mocks is by specifying/verifying method calls on them. 使用模拟的唯一正确方法是在模拟上指定/验证方法调用。

Finally: I would expect that EasyMock, PowerMock(ito) behave in similar ways. 最后:我希望EasyMock,PowerMock(ito)的行为类似。 On the other hand, I wouldn't be surprised either when other mocking frameworks actually behave slightly different. 另一方面,当其他模拟框架实际上表现稍有不同时,我也不会感到惊讶。 I only tested with Mockito because, imho, in 2018, Mockito is the one and only mocking framework one should be using when writing unit tests for the JVM. 我只对Mockito进行了测试,因为,恕我直言,在2018年,Mockito是为JVM编写单元测试时应该使用的唯一的模拟框架。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 @Mock注释下的对象是否应该调用其构造函数? - Should an object under the @Mock annotation have its constructor called? 如何在此模拟对象中设置值 - How to set the value in this mock object @Mock 注释在 Object 映射器上不起作用 - @Mock annotation not working on an Object Mapper 如何模拟void方法,该方法接受模拟对象并期望为模拟对象实例设置一些值 - How to mock a void method which takes mock object and expect to set some value for mock object instance Mock 属性值驻留在构造函数中,并在使用 @injectBean 注释时添加该模拟 - Mock Property value resides in constructor and add that mock while using @injectBean annotation 如何通过注释注入对象并在此对象上设置属性值 - How to inject an object via annotation and set an attribute value on this object 如何使用 Mockito 更改模拟 object 中的值 - How to change a value in a mock object using Mockito 为什么我们应该通过模拟来了解有关邻居对象的信息? - Why we should know information about neighbor object by using mock? 创建对象时如何处理注释和设置默认值 - How to process annotation and set a default value while creating object Spring @Value注释不适用于mockito mock - Spring @Value annotation not working with mockito mock
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM