是否不鼓励在同一场地上使用@Spy和@InjectMocks?

2022-09-01 01:01:34

在我现在正在做的项目中,我经常在一个领域看到并一起使用。我从未在任何教程或其他资源中看到过这种方式。我在谷歌上搜索了这个特定的组合,但在GitHub上除了这个线程之外没有找到其他任何东西:https://github.com/mockito/mockito/issues/169@Spy@InjectMocks

这让我觉得我们正在以一种奇怪的方式使用它。

注意:我认为有时同时使用这两个注释的原因是,如果您仅使用Mockito,请尝试使用no-args构造函数实例化类。如果您没有 no-args 构造函数并添加,则可以使用该对象,而无需空构造函数。@InjectMocks@Spy

编辑:另一个重要用途是,如果您只使用两个注释,则只能使用存根方法。


答案 1

@Spy和@InjectMocks不能很好地一起使用(请参阅Google代码问题#489GitHub问题#169),并且对于它们所做的,它们是否应该一起使用尚不清楚或常见。在写得很好的Mockito用法中,你通常甚至不应该将它们应用于同一个对象。

  • @InjectMocks作为被测系统的一种备用依赖注入:如果你有一个定义正确类型的@Mock或@Spy的测试,Mockito将使用这些测试字段的内容初始化@InjectMocks实例中的任何字段。如果您尚未以其他方式构建受测系统以进行依赖注入(或者如果您使用执行字段注入的 DI 框架),并且希望用模拟替换这些依赖项,这可能很方便。它可能非常脆弱 - 不匹配的字段将被静默地忽略,如果未在初始值设定项中设置,将保留 - 但对于被测系统来说仍然是一个不错的注释。null

  • @Spy,像@Mock一样,旨在设置测试双打;当您有要存根或验证的协作者时,您应该使用它。虽然在某些情况下,您可以监视被测系统,但@Spy和@Mock是针对依赖项的,而不是针对您正在测试的功能的。

理想情况下,你不应该有任何类在同一个测试中同时履行这两个角色,否则你可能会发现自己在编写一个测试,煞费苦心地测试你已经存根的行为,而不是实际的生产行为。无论如何,要准确判断测试涵盖的内容与您已经存根的行为将更加困难。

当然,如果您尝试使用 Mockito 单独测试单个方法,并且您希望在测试一种方法时对一种方法进行存根调用,则这可能不适用。这可以通过创建受测系统的间谍并模拟其某些方法来避免调用协作者来实现。但是,这也可能表明您的类违反了单一责任原则,并且您应该将该类分解为多个协同工作的独立类。然后,在测试中,您可以允许实例只具有一个角色,并且永远不需要同时使用两个注释。


答案 2

每个注释都有不同的用途,只要您需要使用部分模拟,它们就不会清楚地相互踩踏。(又名已经过测试和/或信任的存根相关方法)

例如,您有一个要测试的类,该类具有依赖项注入,该类不必是真实的,因此您希望@InjectMocks。此外,您正在测试的方法调用内部的另一个方法,该方法已经在某处进行了测试,或者它调用了外部引用,该外部引用也很可能是独立测试的。因此,您不希望多次测试相同的方法,并且您的测试代码不应在将来的任何时候受到超出范围的实现更改的影响。

只有@Mock和@Spy,或者@Mock和@InjectMocks对才没有意义。


推荐