是否不鼓励在同一领域使用 @Spy 和 @InjectMocks?
在我现在正在进行的项目中,我经常看到 @Spy
和 @InjectMocks
在字段上一起使用.我从未在任何教程或其他资源中看到过这种方式.我用谷歌搜索了这个特定的组合,但没有在 GitHub 上找到除此线程之外的任何其他内容:https://github.com/mockito/mockito/issues/169
这让我觉得我们以一种奇怪的方式使用它.
注意:我认为同时使用两个注解的原因有时是有意义的,因为如果你只使用 @InjectMocks
Mockito 尝试使用无参数构造函数实例化该类.如果您没有无参数构造函数并添加 @Spy
您可以使用该对象而无需空构造函数.
另一个重要的用途是你只能存根方法如果您只使用两个注释.
解决方案将@Spy 和@InjectMocks 一起使用是不常见的,而且可以说是不合适的.
@InjectMocks 作为被测系统的一种依赖注入:如果您有一个定义了正确类型的 @Mock 或 @Spy 的测试,Mockito 将初始化您的任何字段@InjectMocks 具有这些字段的实例.如果您没有为依赖注入构建被测系统(或者如果您使用执行字段注入的 DI 框架)并且您想用模拟替换这些依赖关系,这可能会很方便.它可能非常脆弱——不匹配的字段将被静默忽略,并且如果没有在初始化程序中设置,将保持 null
——但对于您的测试系统来说仍然是一个不错的注释.p>
@Spy 和@Mock 一样,旨在设置测试替身;当你有一个想要存根或验证的合作者时,你应该使用它.请注意,@Spy 和 @Mock 始终用于依赖项,而不是用于您的测试系统.
理想情况下,您不应该有任何类在同一个测试中同时满足这两个角色,否则您可能会发现自己编写的测试会煞费苦心地测试您存根的行为而不是实际的生产行为.无论如何,要准确判断测试涵盖的内容与您存根的行为将更加困难.
当然,如果您尝试使用 Mockito 单独测试单个方法,并且您希望在测试另一种方法时对一个方法的调用存根,这可能不适用.但是,这也可能表明您的班级违反了单一职责原则,并且您应该将班级分解为多个相互合作的独立班级.然后,在您的测试中,您可以允许实例仅具有一个角色,而永远不需要同时使用两个注释.
In the project I'm working on right now,
I often see the @Spy
and @InjectMocks
used together on a field.
I have never seen it this way in any tutorials or other resources.
I googled about this specific combination but didn't
find anything else other than this thread on GitHub:
https://github.com/mockito/mockito/issues/169
Which makes me think we are using it in a weird way.
Note: The reason why I think using both annotations together
makes sense sometimes is because if you only use @InjectMocks
Mockito tries to instantiate the class with a no-args constructor.
If you don't have a no-args contructor and add @Spy
you can use the object without needing an empty constructor.
Edit: Another important use is that you can only stub methods if you just use both annotations.
解决方案It is uncommon, and arguably inappropriate, to use @Spy and @InjectMocks together.
@InjectMocks works as a sort of dependency injection for the system under test: If you have a test that defines a @Mock or @Spy of the right type, Mockito will initialize any fields in your @InjectMocks instance with those fields. This might be handy if you haven't otherwise structured your system-under-test for dependency injection (or if you use a DI framework that does field injection) and you want to replace those dependencies with mocks. It can be pretty fragile—unmatched fields will be silently ignored and will remain null
if not set in an initializer—but remains a decent annotation for your system under test.
@Spy, like @Mock, is designed to set up test doubles; you should use it when you have a collaborator that you want to stub or verify. Note there that @Spy and @Mock are always meant for dependencies, and not for your system under test.
Ideally, you should not have any class that fulfills both roles in the same test, or else you may find yourself writing a test that painstakingly tests behavior that you've stubbed rather than actual production behavior. In any case it will be more difficult to tell exactly what the test covers versus the behavior you've stubbed.
Of course, this may not apply if you're trying to use Mockito to test a single method in isolation, and you want to stub calls to one method while testing the other. However, this might also be an indication that your class is violating the Single Responsibility Principle, and that you should break down the class into multiple independent classes that work together. Then, in your test, you can allow instances to have exactly one role and never need both annotations at once.
相关文章