给定一个使用Guice @Inject批注在其中注入依赖关系的类,从注入它的类之外获取对该依赖关系的引用有哪些可能的选项?
假设我有以下A类:
public class A {
@Inject
private B b;
}
假设我想测试A类。我编写了一个JUnit测试用例:
public class TestA {
@Inject
private A a;
}
在开始测试A类方法之前,我想在我的测试用例中设置A实例的一些B属性。
在我的测试用例中,在获取对A类中注入的B类实例的引用方面,我有哪些选择?
我可以在A类中添加一个getter来获取对注入的B实例的引用,并在我的测试用例中调用这个getter。虽然,如果A类中还有5个依赖项注入其中,我将不得不在A中为每个依赖项编写5个getter。
另一种选择是用@Singleton注释B类,这样无论我在何处访问它,Guice总是给我相同的B实例。虽然,因为我希望在我的测试用例中访问它而要求Guice将B视为单身,但感觉不对。我可能在B类中有一些我不想在B的所有实例中共享的状态。
是否有比上面列出的更好的选项来获取A中注入的B实例的引用?
修改 请注意,我无法控制A的实例化。我们在内部框架中有一个类将要实例化A.
答案 0 :(得分:2)
单元测试A
最常见和推荐的方法是避免在测试中使用Guice。通过引用您提供的A
来创建B
。
public class A {
private final B b;
@Inject
public A(B b) {
this.b = b;
}
}
在测试代码中,只需创建B
(无论是实际的B
还是模拟),然后自己创建A
;
B b = mock(B.class);
A testUnit = new A(b);
//now you obviously know what b is
如果您确实想在测试中引入Guice,可以使用不同的模块配置来控制B
的实例化方式。由于测试将提供模块和B
的实例,因此在测试中获取B
的实例应该是微不足道的。
答案 1 :(得分:1)
在测试DI时,请查看needle4j框架(以前的针)。它提供了一个JUnit规则,它通过默认提供模拟实例来“模拟”依赖注入,但也允许您通过注释配置显式行为。
然后编写DI单元测试,如
public class ATest {
@Rule
public final NeedleRule needle = NeedleBuilders.needleMockitoRule().build();
@ObjectUnderTest
private A a;
@Inject
private B b;
@Test
public void injects_mock_of_b() {
// when(b.XXX()).thenReturn(...)
// assertThat(a.XXX()) ...
}
}