如何模拟@Inject接口

时间:2016-02-10 20:36:35

标签: java unit-testing junit mockito

我有这个服务接口

public interface ABC {
    public String getAbc();
}

我有这个使用此服务的控制器

public class Do {
    @Inject ABC abc;

    public String doAbc() {
       String a = abc.getAbc();
    }
}

在我的单元测试中,我希望能够模拟出这个ABC而不必提供实际的实现。这是有效的:

public class TestDo {
   @Mock
   private Do do;

   @Mock
   private ABC abc;

   @Before
   public void init() {
       MockitoAnnotations.initMocks(this);
       do.abc = abc;
   }

   @Test
   public void testDo() {
       when(do.doAbc()).thenCallRealMethod();
       do.doAbc();
       assertSomething...
   }
}

但我不想做的是do.abc = abc;,在我的所有搜索中,为了做@InjectMock,我需要提供一个具体的类。有没有办法让我使用界面,但能够将模拟界面注入到do中而不需要在Do Class中暴露我的ABC注入?我想让ABC变成私有变量,并且仍然可以通过Mockito注入接口。

2 个答案:

答案 0 :(得分:4)

public interface ABC {
    public String getAbc();
}

public class Do {

    @Inject
    ABC abc;

    public String doAbc() {
        System.out.println("Injected abc is " + (abc == null ? "null" : "not null"));
        return abc.getAbc();
    }

}


public class TestDo {
    @Mock
    private ABC abc;

    @InjectMocks
    private Do ddo;

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void simpleTest() {
        System.out.println(ddo.doAbc());
    }

}

输出是:

Injected abc is not null
null

答案 1 :(得分:3)

您给出的示例是构造函数注入的完美案例:您可以将您的依赖项设置为私有(甚至是最终的,在实际情况下总是更好)并且仍然构建一个实例而不需要注入框架:

public class Do {
    private final ABC abc;

    @Inject
    public Do(final ABC abc) {
        this.abc = abc;
    }

    public String doAbc() {
       String a = abc.getAbc();
    }
}