【问题标题】:Ignore mocked object transitive dependencies忽略模拟对象传递依赖
【发布时间】:2014-01-20 15:01:40
【问题描述】:
当一个类实现一个接口时,我们所要做的就是模拟该接口。
但是在某些情况下,类没有实现接口,在这种情况下,将类绑定到模拟会导致 guice 获取模拟对象依赖项。
澄清一下:
class A {
@Inject B;
}
class B{
@Inject C;
}
bind(a.class).toInstance(mock(B.class));
在这种情况下,我不关心 B 的依赖关系,但 guice 仍然会尝试将 C 注入到 B 中。
有没有办法在不定义接口的情况下避免这种情况?
【问题讨论】:
标签:
dependency-injection
mocking
mockito
guice
【解决方案1】:
首先,我强烈建议不要在单元测试中使用依赖注入。当您对单个类进行单元测试时,您应该创建它并通过构造函数或方法直接传递其依赖项。那你就不会有这些问题了。
但是,当您编写集成测试时,情况就不同了。您的问题有多种解决方案。
确保所有类仅通过可注入构造函数接收依赖项。这样 Guice 就不会注入任何东西,因为该对象将由 Mockito 创建。
-
使用提供者(和范围,如果需要)。以下相当于您尝试不注入 B (我假设您的意思是 bind(B.class).toInstance(mock(B.class)):
bind(B.class).toProvider(new Provider<B> {
@Override
public B get() {
return mock(B.class);
}
}).in(Singleton.class);
您应该调整范围以满足您的需求。
【解决方案2】:
使用 Mockito 部分解决这个问题非常容易。
您需要像这样使用@Mock 和@InjectMocks 注释
ATest{
@Mock B;
@InjectMocks A;
public void setUp(){
MockitoAnnotations.initMocks(this);
}
}
这样 Mockito 将执行注入而不是 guice,有几个 restrictions 可以成功注入模拟。
在您的代码对类有很强的依赖关系之前,这非常有效。
假设在 A 内部我有类似 C obj = new C();和 C 注入了字段。