如何在编写 espresso 测试时设置 dagger-android 2.15 后进行模拟?

How to mock after setup dagger-android 2.15 when writing espresso tests?

如果我们只使用普通匕首 2。在 application class 中,我们将有一个 属性 持有 AppComponent。然后我们可以在浓缩咖啡测试期间交换它。

但是当我使用 dagger-android 2.15 设置我的项目时。如果采用过多的 Dagger 魔法,事情就会变得更加含蓄。代码更干净,但让测试有点困难。

这是application class:

class App : DaggerApplication() {
    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent
            .builder()
            .create(this)
            .build()
    }
}

这是主页活动

class HomeActivity : DaggerAppCompatActivity() {
    @Inject
    lateinit var userPreference: UserPreference

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_home)

        if (!this.userPreference.memberRegistered) {
            goToActivity(EntryActivity::class.java)
        }
    }
}

以这段代码为例。如何模拟注入的 userPreference.memberRegistered 这可能是下面的 HTTP 调用?

我昨天写了一篇博客 post 解释了如何做到这一点:https://dev.to/autonomousapps/the-daggerandroid-missing-documentation-33kj

我不打算为这个答案重复整个 post(用 Dagger 正确设置测试工具需要数百个单词和代码行),但尝试总结一下:

  1. debug 源集中添加自定义应用程序 class(我假设它也适用于 androidTest 源集,但我没有尝试过)。
  2. 您还需要在同一源集中的 AndroidManifest.xml 中引用此应用程序。
  3. 在您的 androidTest class 中创建一个 "Test component" 从您的生产顶级组件扩展并构建它。
  4. 使用该测试组件注入您的应用程序,这意味着您刚刚将整个 Dagger 依赖关系图替换为您专门为测试套件定义的新依赖关系图。
  5. 利润。

对于那些对此感兴趣的人,我得到了一个 blog 详细的步骤:

基本上,这个想法是:

  1. 您仍然在@Module 中生成用于注入的实例
  2. 但是我们将创建新的@Component A 仅用于测试
  3. 这个@Component 将有一个方法来获取那个@Module
  4. 在测试期间,我们将应用程序使用的 @Component 与我们的组件 A 交换

那就简单了:

  • 没有 DaggerMock

    • 在@Module 中,您只是 return mockito mock,而不是 return 真实实例。
  • 使用 DaggerMock

    • 您声明要交换的类型并模拟它
    • 然后您可以使用模拟。
    • 无需更改@Module

它受到@AutonomousApps 的解决方案的启发,但不同之处在于现在您不需要为每个测试编写@Component、@Module class。

在尝试了多种方法后,this 是唯一对我有用的方法。