Android 如何将测试覆盖注入默认依赖关系图?

Android 如何将测试覆盖注入默认依赖关系图?,android,kotlin,kodein,Android,Kotlin,Kodein,我想使用Kodein将模拟覆盖注入到我的Android检测测试中。我不知道哪种方法是最好的。以下是我的想法: 我的应用程序使用KodeinAware应用程序类。服务的Kodein实例包含我的应用程序所需的所有依赖项 在我的测试中,我想为特定依赖注入模拟覆盖,以测试应用程序在各种情况下的行为 覆盖对于每个测试都应该是不同的,并且应该在测试运行之前/期间注入 在这种情况下,测试是明智的,还是有一种更简单、更适合的方法(如果是,是哪种方法)?如果您的测试提供了一个Kodein实例(这意味着它可以使

我想使用Kodein将模拟覆盖注入到我的Android检测测试中。我不知道哪种方法是最好的。以下是我的想法:

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

在这种情况下,测试是明智的,还是有一种更简单、更适合的方法(如果是,是哪种方法)?

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

val testKodein = Kodein {
    extend(appKodein())

    bind<MyManager>(overrides = true) with singleton { mock<MyManager>() }
}
val testKodein=Kodein{
扩展(appKodein())
使用单例{mock()}绑定(overrides=true)
}

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

我现在在自定义
应用程序
类中使用
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)
    }
}
class ResetKodeinRule : ExternalResource() {
    override fun before() {
        val app = InstrumentationRegistry.getInstrumentation().targetContext.asApp()
        app.kodein.clear()
        app.kodein.addImport(appDependencies(app))
    }
}
我创建了一个JUnit规则,在每次测试之前重置依赖关系图

class AppTestRunner : AndroidJUnitRunner() {
    override fun callApplicationOnCreate(app: Application) {
        app.asApp().kodein.mutable = true
        super.callApplicationOnCreate(app)
    }
}
class ResetKodeinRule : ExternalResource() {
    override fun before() {
        val app = InstrumentationRegistry.getInstrumentation().targetContext.asApp()
        app.kodein.clear()
        app.kodein.addImport(appDependencies(app))
    }
}

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

我在单元测试中使用这种方法,即在验证注入类的正确行为的测试中。然而,在我的工具中,更具体地说,在我的功能测试中,我正在测试我的实际应用程序的一个实例。为了使测试具有确定性,我用mock替换图形中的某些依赖项。Kodein是由
应用程序
实例提供的,因此它类似于“真正的Kodein”。我现在正在测试一种可配置的kodein方法,一旦有了一些结果就会回来。