【问题标题】:How to inject test overrides into the default dependency graph?如何将测试覆盖注入到默认依赖图中?
【发布时间】:2017-02-21 16:17:05
【问题描述】:

我想使用 Kodein 将模拟覆盖注入到我的 Android 仪器测试中。我不知道哪种方法是执行此操作的最佳方法。这是我的想法:

  • 我的应用程序使用KodeinAware 应用程序类。服务的 Kodein 实例包含我的应用程序所需的所有依赖项。
  • 在我的测试中,我想为特定依赖项注入模拟覆盖,以测试应用在各种情况下的行为。
  • 每个测试的覆盖应该不同,并且应该在测试运行之前/期间注入。

configurable Kodein extension 在这种情况下是否合理,或者是否有更简单、更适合的方法(如果有,是哪种)?

【问题讨论】:

    标签: android kotlin kodein


    【解决方案1】:

    如果为您的测试提供了一个 Kodein 实例(这意味着它可以使用与您的 Application 持有的对象不同的 Kodein 对象),那么推荐的方法是创建一个新的 Kodein 对象,该对象扩展应用程序之一并覆盖所有必要的绑定。

    val testKodein = Kodein {
        extend(appKodein())
    
        bind<MyManager>(overrides = true) with singleton { mock<MyManager>() }
    }
    

    仅当您使用静态的“一个真正的 Kodein”时,才建议使用可配置的 Kodein 选项。使用它可以防止并行运行您的测试(因为它们都访问相同的 Kodein 实例),并强制您在每个测试之间 clear ConfigurableKodein 并在每次不同的覆盖时重新声明。

    【讨论】:

    • 我在我的单元测试中使用这种方法,即在验证注入类的正确行为的测试中。但是,在我的仪器中,更具体地说,在我的功能测试中,我正在测试我的真实应用程序的一个实例。为了使测试具有确定性,我用模拟替换了图表中的某些依赖项。 Kodein 由Application 实例提供,因此它就像“一个真正的Kodein”。我现在正在测试一种可配置的 kodein 方法,一旦有结果就会回来。
    【解决方案2】:

    我现在在我的自定义 App 类中使用 ConfigurableKodein

    class App : Application(), KodeinAware {
        override val kodein = ConfigurableKodein()
    
        override fun onCreate() {
            super.onCreate()
    
            // A function is used to create a Kodein module with all app deps.
            kodein.addImport(appDependencies(this))
        }
    }
    
    // Helper for accessing the App from any context.
    fun Context.asApp() = this.applicationContext as App
    

    在我的AppTestRunner 类中,我声明配置是可变的。这样我就可以在每次测试之间重置它的配置。

    class AppTestRunner : AndroidJUnitRunner() {
        override fun callApplicationOnCreate(app: Application) {
            app.asApp().kodein.mutable = true
            super.callApplicationOnCreate(app)
        }
    }
    

    我创建了一个 JUnit 规则,在每次测试之前重置依赖关系图。

    class ResetKodeinRule : ExternalResource() {
        override fun before() {
            val app = InstrumentationRegistry.getInstrumentation().targetContext.asApp()
            app.kodein.clear()
            app.kodein.addImport(appDependencies(app))
        }
    }
    

    在我的测试中,我现在可以检索App.kodein 实例并注入覆盖原始图依赖关系的模拟。唯一需要保证的是测试的活动是在配置模拟之后启动的,或者行为是不可预测的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-26
      • 2017-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多