为什么Mockito @InjectMocks可能是一件可以避免的事情?

Mar*_*szS 7 java unit-testing dependency-injection mockito

为什么@InjectMocks这种测试可能会避免这种情况.

@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {

    @Mock
    private Bar bar;

    @InjectMocks
    private Foo foo; // created by Mockito

    @Test
    public void shouldCallMethod() {

        // when
        foo.myMethod();

        // then
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

Foo.java

public class Foo {

    private final Bar bar;

    public Foo(Bar bar) {
        this.bar = bar;
    }
...
Run Code Online (Sandbox Code Playgroud)

我在对这个答案的评论中读到了这个:https://stackoverflow.com/a/21172873/516167

关于@InjectMocks

标记应在其上执行注射的区域.

  • 允许速记模拟和间谍注射.
  • 最大限度地减少重复模拟和间谍注射.

参考:@InjectMocks JavaDoc.

isa*_*sah 2

我认为唯一的缺点是你必须遵守其规则。如果您不使用,您可能拥有更多控制权@InjectMocks

从他们的文档中,我添加了一些粗体

Mockito 将尝试仅按顺序通过构造函数注入、setter 注入或属性注入来注入模拟,如下所述。如果以下任一策略失败,则 Mockito不会报告失败;即您必须自己提供依赖项。

构造函数注入;选择最大的构造函数,然后仅使用测试中声明的模拟来解析参数。注意:如果找不到参数,则传递 null。如果需要不可模拟类型,则构造函数注入将不会发生。在这些情况下,您必须自己满足依赖关系。

属性设置器注入;模拟将首先按类型解析,然后,如果有多个相同类型的属性,则通过属性名称和模拟名称的匹配来解析。注意1:如果你有相同类型(或相同擦除)的属性,最好用匹配的属性命名所有@Mock注释的字段,否则Mockito可能会感到困惑并且不会发生注入。

注意2:如果@InjectMocks实例之前没有初始化并且有一个无参数构造函数,那么它将用这个构造函数初始化。

现场注入;模拟将首先按类型解析,然后,如果有多个相同类型的属性,则通过字段名称和模拟名称的匹配来解析。注意1:如果你有相同类型(或相同擦除)的字段,最好用匹配的字段命名所有@Mock注释的字段,否则Mockito可能会感到困惑并且不会发生注入。

注意2:如果@InjectMocks实例之前没有初始化并且有一个无参数构造函数,那么它将用这个构造函数初始化。