2

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

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

在这种情况下,可配置的 Kodein 扩展是否明智,或者是否有更简单、更适合的方法(如果有,是哪种)?

4

2 回答 2

5

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

val testKodein = Kodein {
    extend(appKodein())

    bind<MyManager>(overrides = true) with singleton { mock<MyManager>() }
}

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

于 2016-10-13T13:34:56.527 回答
5

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

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实例并注入覆盖原始图依赖关系的模拟。唯一需要保证的是被测试的activity是在配置mock之后启动的,或者行为是不可预测的。

于 2016-10-14T11:27:35.647 回答