[译]使用 Espresso 模拟 Application 实现依赖注入

原文:Mock Application in Espresso for Dependency Injection
作者:Chiu-Ki Chan
译者:lovexiaov

我看了 Artem Zinnatullin 写的使用 Dagger,Robolectric 和 InStrumentation 在单元测试,集成测试与功能测试中模拟依赖(译者注:这里将链接替换成了中译版本,文章中有原文链接)这篇好文。其中我最喜欢的部分是在测试中使用不同的 application 来提供不同的依赖,而我决定使用 Espresso 实现它。

通过自定义测试运行器模拟 application

我当前实现依赖注入(译者注:下文统一使用 DI)的方法是在我的测试 application 中暴露一个 setComponent 函数来提供测试组件,这样并不是太好,因为理想情况下 application 中不能包含测试指定代码。

一种新的实现方式是在 androidTest 文件夹中使用 application 的子类 ,并在测试时通过自定义测试运行器加载它。

public class DemoApplication extends Application {
  private final DemoComponent component = createComponent();

  protected DemoComponent createComponent() {
    return DaggerDemoApplication_ApplicationComponent.builder()
        .clockModule(new ClockModule())
        .build();
  }

  public DemoComponent component() {
    return component;
  }
}

在此 application 中,我们使用 createComponent() 实例化的 DemoComponent,并且将它存储为 final 变量待以后使用。

public class MockDemoApplication extends DemoApplication {
  @Override
  protected DemoComponent createComponent() {
    return DaggerMainActivityTest_TestComponent.builder()
        .mockClockModule(new MockClockModule())
        .build();
  }
}

测试时,我们继承自己的 application 并重写 createComponent 来提供测试组件。

我们需要自定义测试运行器以在测试是使用模拟 application:

public class MockTestRunner extends AndroidJUnitRunner {
  @Override
  public Application newApplication(
      ClassLoader cl, String className, Context context)
      throws InstantiationException, 
             IllegalAccessException, 
             ClassNotFoundException {
    return super.newApplication(
      cl, MockDemoApplication.class.getName(), context);
  }
}

我们给出 MockDemoApplication.class.getName() 作为类名,这样测试运行器将会加载模拟 application 而不是真实的 application。

按应用还是按测试?

此方式与 setComponent 有些许不同,因为我们只初始化测试组件一次,而不是每个测试方法执行前都要初始化。确保你在每次测试方法执行前都清除了测试模块的状态,这样每个测试方法都能从零开始执行。

源码

我已经在我的两个仓库中使用了此方式:

  • android-test-demo:迷你样例演示的此概念。
  • friendspell:一个真实的应用展示了怎样在每个测试之前清除状态。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,385评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,327评论 25 709
  • 今天是围棋第二课。 临近下班,开始下雨。看看问题似乎不大,打算徒步过去上课。群里已经开始请假了,后面还跟风+1。关...
    金明啊阅读 2,744评论 0 1
  • 知道我们“幸福家庭俱乐部”要做公益读书会,反对的人不少。 理由主要有二:一、石狮人都在忙生意,喜欢读书的人少得很。...
    _大陈_阅读 3,114评论 1 0
  • 兰顿酒足饭饱之后看着忙碌收拾碗具的妻子说“我说,咱们离婚怎么样?你再嫁一个老公,我再娶个老婆”妻子便说“好啊,保证...
    髑髏阅读 1,027评论 0 0