Dagger2:如何在 JUnit 测试中使用 @Inject?

Ala*_*n47 4 java testing junit dependency-injection dagger-2

我希望能够使用 Dagger 2 将依赖项注入 JUnit 测试(我是这个框架的新手)。从 Spring 开始,您可以执行以下操作:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = MyApplication.class)
public class MyTestClass {

    @Autowired
    private MyService service;

    @Test
    public void testMySerivce() { /* ... */ }

}
Run Code Online (Sandbox Code Playgroud)

...但是对于 Dagger 2,我还没有找到不依赖于显式DaggerMyComponent.builder().build().myService().

理想情况下,我会想象解决方案如下所示:

// tell JUnit that dagger needs to do some post processing
@RunWith(DaggerJUnit4Runner.class)
// tell dagger which component classes to use for injection
@Components(MyComponent.class)
public class MyTestClass {

    @Inject
    private MyService service;

    @Test
    public void testMySerivce() { /* ... */ }

}
Run Code Online (Sandbox Code Playgroud)

不幸的是,没有DaggerJunit4Runner

任何关于如何实现这一点的提示将不胜感激。

Jef*_*ica 5

我还没有看到任何内置功能,或任何支持此功能的突出测试库。

Dagger 在编译时完成所有的依赖连接,并且只以你告诉它的方式进行;与 Spring 不同的是,没有编写代码来在运行时读取测试类或提供它需要的依赖项。Dagger 对 Guice 和 Spring 的吸引力来自于编译时编译、验证和优化。尽管您所描述的内容非常有用,但这种反思与 Dagger 的原始动机背道而驰。要么您的 Dagger 组件使用生成的代码编译以注入测试,要么您需要能够像上面列出的那样独立地提取这些依赖项。

对于单元测试,您可能需要跳过 Dagger 并手动创建您的类或它们的模拟;对于系统或集成测试,您需要在组件定义中公开您需要的所有类。如果您想用测试替身替换依赖项以实现可重复性或隔离性,您需要使您的组件具有足够的可配置性以接受替换实现,或者您需要创建一个新的用于测试的组件实现,它使用测试替身代替真正的实现。