在我现在正在进行的项目中,我经常看到@Spy
和@InjectMocks
在一个字段上一起使用。我从未在任何教程或其他资源中看到过这种方式。我在谷歌上搜索了这个特定的组合,但没有在GitHub上找到除此线程之外的任何其他内容:https://github.com/mockito/mockito/issues/169
这让我觉得我们在以一种奇怪的方式使用它。
注:我之所以认为同时使用这两个注释有时是有意义的,因为如果只使用@InjectMocks
Mockito尝试使用无args构造函数实例化类。如果没有无参数构造函数并添加@Spy
,则可以使用该对象而不需要空构造函数。
编辑:另一个重要的用途是只能存根方法如果同时使用这两个注释。
@Spy和@InjectMocks不能很好地一起使用(请参阅Google Code第489期和GitHub第169期),对于它们的作用,它们是否应该一起使用还不清楚或不常见。在编写良好的Mockito用法中,通常甚至都不希望将它们应用于同一对象。
-
@InjectMocks作为被测系统的一种替代依赖注入:如果您的测试定义了正确类型的@Mock或@Spy,Mockito将使用这些测试字段的内容初始化@InjectMocks实例中的任何字段。如果您还没有为依赖项注入构建测试中的系统(或者如果您使用的是进行字段注入的DI框架),并且您想用mock替换这些依赖项,那么这可能会很方便。它可能非常脆弱——不匹配的字段将被静默地忽略,如果不在初始值设定项中设置,则将保持
null
——但对于测试中的系统来说,它仍然是一个不错的注释。 -
@Spy和@Mock一样,设计用于设置测试替身;当您有一个想要存根或验证的合作者时,应该使用它。尽管在某些情况下,可以监视测试中的系统,但@spy和@Mock是用于依赖关系的,而不是用于测试的功能。
理想情况下,您不应该在同一测试中拥有任何同时满足这两个角色的类,否则您可能会发现自己正在编写一个测试,该测试会煞费苦心地测试您丢弃的行为,而不是实际的生产行为。在任何情况下,都很难准确地判断测试涵盖了什么,而不是您所拦截的行为。
当然,如果您试图使用Mockito单独测试单个方法,并且希望在测试另一个方法的同时存根调用一个方法,则这可能不适用。这可以通过创建被测系统的间谍并嘲笑其一些方法来避免调用合作者来实现。然而,这也可能表明您的类违反了单一责任原则,并且您应该将该类分解为多个协同工作的独立类。然后,在测试中,您可以允许实例只具有一个角色,而不需要同时使用两个注释。
每个注释都有不同的目的,只要需要使用部分mock,它们就不会明显地相互影响。(又称已经测试和/或信任的与存根相关的方法)
例如,您有一个要测试的类,它具有不必是真实的依赖项注入,因此您希望@InjectMocks。此外,您正在测试的方法调用内部的另一个方法,该方法已经在某个地方进行了测试,或者它调用的外部引用也很可能是独立测试的。所以,您不想多次测试相同的方法,而且您的测试代码在未来任何时候都不应该受到范围外实现更改的影响。
只有@Mock&间谍,或@Mock&InjectMocks对毫无意义。