【问题标题】:Android plain Junit with Dagger 2带有 Dagger 2 的 Android 普通 Junit
【发布时间】:2016-08-19 13:56:13
【问题描述】:

我曾经在 MVP 中工作,我通常使用普通的 Junit(不是 Instrumentation !)来测试我的 Presenters,因为 Presenters 只有业务逻辑,没有任何对 Android 内部的引用。

现在通过切换到 Dagger 2,我了解到我在为我的应用组件设置“TestModule”时遇到了问题。

  1. 在测试类中无法创建组件(可能是因为“apt”没有在测试类中运行)
  2. 没有找到任何将 Dagger 用于标准 Junit 测试的示例。我发现的每个示例都只依赖于 Instrumentation 测试或 Roboelectric(它基本上模拟了活动和其他 Android 相关的东西),但这对我来说只是一个 UI 测试,我不需要。

为了清楚起见,我说的是位于 app->src->test 文件夹而不是 app->src->androidTest 的测试!

那我做错了吗?还是错过了什么?谁能解释或举例说明如何在正常的单元测试中使用 Dagger 2?

【问题讨论】:

    标签: android junit dagger-2


    【解决方案1】:

    我不确定我的解决方案是否适合您,但我认为没有理由不适合。 首先我创建了 testInjectionComponent

    @Singleton
    @Component(modules = {MockNetworkModule.class})
    public interface MockInjectionComponent extends InjectionComponent {
    void inject(DaggerUnitTest daggerUnitTest);
    }
    

    然后我的单元测试我在 before 方法中添加了注入。像这样:

    @Before
    public void setUp() throws Exception {
        MockInjectionComponent mockInjectionComponent = DaggerMockInjectionComponent
                .builder()
                .mockNetworkModule(new MockNetworkModule())
                .build();
        mockInjectionComponent.inject(this);
    }
    

    然后我只是注释我的注入对象。

    编辑: 不要忘记在您的 app.gradle 文件中添加testApt "com.google.dagger:dagger-compiler:$daggerVersion"

    【讨论】:

    • 已经试过了。当您尝试调用 DaggerMockInjectionComponent.builder() 时它不会编译...它说“...错误:(41、54)错误:找不到符号方法 builder()...”这是 Github 参考:@ 987654321@
    • @Ivelius 必须在 Dagger 前面加上 DaggerMockAppComponent 然后让你的项目让 Dagger 可以生成文件,它会提示你导入它。
    • 是的,只是一个错字。我提交了修复程序。它仍然是一样的......不编译。您可以随意签出这个小型测试项目并亲自查看...github.com/ivelius/BitcoinGraph/blob/DaggerTests/app/src/test/…
    • 好的,在你的 build.gradle 添加 testApt 'com.google.dagger:dagger-compiler:2.5' 然后编译
    • 来吧;你不能只写“然后我只是注释我的注入对象。”。您必须意识到对于尝试学习 Dagger/DI 的人来说,这是一个令人生气的细节?请给我们代码。
    【解决方案2】:

    正如接受的答案所述。不要忘记添加:

    对于 Java

    安卓测试

    androidTestAnnotationProcessor 'com.google.dagger:dagger-compiler:$dagger_version'
    

    JUnit 测试

    testAnnotationProcessor 'com.google.dagger:dagger-compiler:$dagger_version'
    

    对于 Kotlin

    安卓测试

    kaptAndroidTest 'com.google.dagger:dagger-compiler:$dagger_version'
    

    JUnit 测试

    kaptTest 'com.google.dagger:dagger-compiler:$dagger_version'
    

    【讨论】:

      【解决方案3】:

      您不需要任何匕首来测试您的演示者。 Dagger 的工作是填充类的依赖关系(依赖注入)。

      例如你有这个 Presenter:

      public class MyPresenter {
      
          Database database;
          ApiService apiService;
      
          @Inject
          public MyPresenter(final Database database, final ApiService apiService) {
              this.database = database;
              this.apiService = apiService;
          }
      }
      

      Dagger 将为您的 Presenter 提供 databaseapiService 对象,供您的 Presenter 使用。在运行实际应用程序(不是测试)时,这些将是具有真实功能的真实对象。

      在测试演示者时,您只想测试演示者,其他一切都应该模拟。

      因此,当您在 PresenterTest 中创建演示者时,您会使用 databaseapiService 的模拟版本创建它。

      然后您可以测试演示者如何与这些对象交互

      一个。模拟对象的行为,如

      when(database.getSomething()).thenReturn(something)
      

      b.验证您的演示者是否对这些对象执行了您希望它执行的操作,例如

      verify(database).saveSomething()
      

      (伪代码)

      模拟的标准方式是 Mockito。

      【讨论】:

      • 感谢您的回答。这正是我目前所做的。但是如果我不能使用 dagger 来交换我的模块(真实模块和测试模块),那么我就会失去在我的项目中使用 DI 的主要原因之一。我更愿意定义一个测试模块,该模块将由 dagger “提供”那些模拟的数据库和 apiService 对象。这就是 DI 的重点!
      • 如果这是您目前所做的,请继续这样做。否则请解释为什么您认为您需要一个测试组件来进行单元测试并发布一些代码:)
      • 也许不是代码,而是对DI的核心理解。 DI 使编写可测试代码变得更容易已经不是什么秘密了。检查维基百科中 DI 的定义。如果我们在测试期间自己将参数注入到演示者,我们基本上是在 DI 设计模式中充当“注入器”。为什么不为此使用框架?如果 Dagger 永远不会互换,为什么我们需要不同的模块?
      • “为什么不使用这个框架呢?”因为更多的工作没有收获。同样,一些代码将有助于了解为什么您认为您的单元测试需要 dagger 组件。 “如果 Dagger 永远不会互换,为什么我们还需要不同的模块呢?”在进行 Espresso(或其他仪器测试)时,为测试组件交换真实组件非常有用,您无法控制类的实例创建(因为 Dagger 在运行时创建实例)但仍希望它们使用您的模拟依赖项。
      【解决方案4】:

      您可以通过两种方式将真实模块替换为假模块:在编译时使用 google architecture samples 推荐的风格或在运行时创建一个抽象方法,该方法在生产代码中注入真实的东西并在测试中注入假的依赖项代码。在第二种情况下,您的测试必须继承您要模拟的类并从头开始构建组件

      【讨论】:

      • 当我使用 Flavors 代替我的 Modules 时,即使没有匕首我也可以做到。正如谷歌示例中所建议的那样,它们只是具有不同版本的 Injector 类,其作用类似于提供者。基本上他们在没有 Dagger 的情况下进行 DI。问题是如何用匕首做到这一点?一般来说 。如果我需要变通方法来使用 Dagger 进行 DI,我为什么需要 Dagger? :D
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-31
      相关资源
      最近更新 更多