在Guice中访问注入的依赖项

时间:2014-05-11 15:38:52

标签: java singleton guice

给定一个使用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.

2 个答案:

答案 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()) ...
}
}