不鼓励在同一个字段上使用@ Spy和@InjectMocks吗?

时间:2016-07-25 12:05:42

标签: java mocking mockito

在我正在进行的项目中,我经常看到@Spy@InjectMocks在一个字段上一起使用。但我从未在任何教程或其他资源中看到过这种方式。我用Google搜索了这个特定的组合,但除了GitHub上的这个帖子之外没有找到任何其他内容: https://github.com/mockito/mockito/issues/169

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

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

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

2 个答案:

答案 0 :(得分:30)

一起使用@ Spy和@InjectMocks是不常见的,也可能是不合适的。

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

像@Mock一样,

@Spy 旨在设置测试双打;当你有一个想要存根或验证的协作者时,你应该使用它。请注意,@ Spy和@Mock总是指表示依赖项,而不是您测试的系统

理想情况下,您不应该在同一个测试中拥有任何满足这两个角色的类,否则您可能会发现自己正在编写一个测试,该测试会仔细测试您存在的行为,而不是实际的生产行为。在任何情况下,更准确地说出测试涵盖的内容与您存在的行为相比将更加困难。

当然,如果您尝试使用Mockito单独测试单个方法,并且您希望在测试另一个方法时将调用存根到一个方法,则可能不适用。但是,这也可能表明您的类违反了单一责任原则,并且您应该将该类分解为多个可以协同工作的独立类。然后,在测试中,您可以允许实例只有一个角色,而且不会同时需要两个注释。

答案 1 :(得分:7)

每个注释都有不同的用途,只要你需要使用部分模拟,它们就不会相互衔接。 (a.k.a.已经测试和/或信任的存根相关方法)

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

只有@Mock& @Spy,或@Mock& @InjectMocks对毫无意义。