【问题标题】:How to mock after setup dagger-android 2.15 when writing espresso tests?如何在编写 espresso 测试时设置 dagger-android 2.15 后进行模拟?
【发布时间】:2018-04-18 09:44:52
【问题描述】:

如果我们只使用普通的匕首 2。在 application 类中,我们将拥有一个包含 AppComponent 的属性。然后我们可以在 espresso 测试期间交换它。

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

这是application 类:

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

这是 HomeActivity

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 调用?

【问题讨论】:

  • 其实我昨天刚刚写了一篇关于这个的博文:dev.to/autonomousapps/…
  • @AutonomousApps 阅读!谢谢!真的很棒的教程!似乎只需要用接口替换 DaggerApplication。

标签: android kotlin mocking android-espresso dagger


【解决方案1】:

对于那些对此感兴趣的人,我得到了一个blog,其中包含详细的详细信息:

基本上,这个想法是:

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

那么事情就简单了:

  • 没有 DaggerMock

    • 在 @Module 中,您只需返回 mockito 模拟,而不是返回真实实例。
  • 使用 DaggerMock

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

它的灵感来自@AutonomousApps 的解决方案,但不同之处在于您现在不需要为每个测试类编写@Component、@Module。

【讨论】:

  • 我实际上认为它是一个功能,我每个测试都有一个组件。这使我可以完全控制每个测试。它们可以像我喜欢的那样深或浅(单元测试与端到端测试)。
  • 没错,但是如果您只需要从@Module 模拟提供程序,DaggerMock 会更容易,我只是在整个测试中重用 AppComponentForTest... 无论如何,谢谢!没有你的博客,将很难解决。 :D
  • 很高兴它有帮助!
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

    • 对我来说似乎很老套。此外,如果您在 debug 中添加这个新应用程序,这意味着您在调试模式以及测试模式下使用模拟测试依赖项,理论上您通常在调试模式下运行您的 prod 代码,以便您可以调试 prod 代码跨度>
    • 有没有办法只创建一个仅用于测试的应用程序?
    • 您显然不能在开发版本中注入模拟依赖项,因为您永远不会在产品代码中包含测试库。
    • 是的,所以上面的方法行不通!您将在调试开发代码上使用可测试的模拟!
    • 是的,你会的,这是错误的方式,你的思维方式是有缺陷的。改用匕首模拟并正确执行。这是一个糟糕的想法,每次您使用应用程序的调试版本时,它都会使用位于 ApplicationDebug 类中的模拟组件等。
    猜你喜欢
    • 2014-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-25
    • 2022-11-20
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多