我理解Dagger2是如何工作的,
据我所知,它允许轻松交换依赖关系,因此我们可以使用模拟进行测试。
重点是,我不确定我是否理解如何为测试和调试/生产提供不同的Dagger2组件实现。
我是否需要创建2个Gradle productFlavors(例如" Production" /" Test") 那将包含2个不同的组件定义?
或者我可以指定我想使用模拟组件进行测试编译,非模拟组件用于非测试构建吗?
我很困惑,请澄清一下会很棒!
非常感谢!
答案 0 :(得分:2)
单元测试
不要使用Dagger进行单元测试
对于使用@Inject
带注释的构造函数测试类,您不需要匕首。而是使用伪造或模拟依赖的构造函数创建实例。
final class ThingDoer {
private final ThingGetter getter;
private final ThingPutter putter;
@Inject ThingDoer(ThingGetter getter, ThingPutter putter) {
this.getter = getter;
this.putter = putter;
}
String doTheThing(int howManyTimes) { /* … */ }
}
public class ThingDoerTest {
@Test
public void testDoTheThing() {
ThingDoer doer = new ThingDoer(fakeGetter, fakePutter);
assertEquals("done", doer.doTheThing(5));
}
}
功能/集成/端到端测试
功能/集成/端到端测试通常使用生产 应用程序,但用伪造[^ fakes-not-mocks]代替持久性, 后端和auth系统,留下应用程序的其余部分 正常运作。这种方法有助于拥有一个(或者一个 小有限数量的测试配置,其中测试 配置替换了prod配置中的一些绑定。
这里有两个选项:
选项1:通过子类化模块覆盖绑定
@Component(modules = {AuthModule.class, /* … */})
interface MyApplicationComponent { /* … */ }
@Module
class AuthModule {
@Provides AuthManager authManager(AuthManagerImpl impl) {
return impl;
}
}
class FakeAuthModule extends AuthModule {
@Override
AuthManager authManager(AuthManagerImpl impl) {
return new FakeAuthManager();
}
}
MyApplicationComponent testingComponent = DaggerMyApplicationComponent.builder()
.authModule(new FakeAuthModule())
.build();
选项2:单独的组件配置
@Component(modules = {
OAuthModule.class, // real auth
FooServiceModule.class, // real backend
OtherApplicationModule.class,
/* … */ })
interface ProductionComponent {
Server server();
}
@Component(modules = {
FakeAuthModule.class, // fake auth
FakeFooServiceModule.class, // fake backend
OtherApplicationModule.class,
/* … */})
interface TestComponent extends ProductionComponent {
FakeAuthManager fakeAuthManager();
FakeFooService fakeFooService();
}
有关implemented的更多信息。