【问题标题】:Android Tests: use Dagger2 + GradleAndroid 测试:使用 Dagger2 + Gradle
【发布时间】:2016-03-10 09:49:40
【问题描述】:

我了解 Dagger2 的工作原理,

我知道它允许轻松交换依赖关系,因此我们可以使用模拟进行测试。

关键是我不确定我应该如何为测试和调试/生产提供不同的 Dagger2 组件实现。

我是否需要创建 2 个 Gradle productFlavor(例如“Production”/“Test”) 将包含 2 个不同的组件定义?

或者我可以指定我想使用模拟组件进行测试编译和非模拟组件用于非测试构建吗?

我很困惑,请澄清一下会很好!

非常感谢!

【问题讨论】:

  • 如您所知,dagger 提供了传递您的类所依赖的对象的方法,在提供的方法中放置一个标志以检查静态变量 isTest 是否为真或假,如果为真则返回模拟对象
  • 是的,这是一个选项,但丑不是吗?:-(
  • 很难看有更好的解决方案尝试看看著名的开源 android 应用程序也许你可以从他们那里得到一些东西

标签: android testing gradle dagger-2


【解决方案1】:

单元测试

不要使用 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[^fakes-not-mocks] 代替持久性, 后端和身份验证系统,将应用程序的其余部分留给 正常运行。这种方法适合拥有一个(或者可能是一个 小有限数量)的测试配置,其中测试 配置替换了 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();
}

更多信息请关注official documentation testing page

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-19
    • 1970-01-01
    • 2015-05-29
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    • 2015-01-04
    • 1970-01-01
    相关资源
    最近更新 更多