如何将测试替代注入默认依赖关系图中?

dav*_*ber 2 android kotlin kodein

我想使用Kodein将模拟替代插入我的Android工具测试中。我不知道哪种方法最合适。这就是我的想法:

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

配置Kodein扩展在这种情况下明智的,或者是有一个更简单,更适合的方法(如果有的话,它)?

Sal*_*RYS 5

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

val testKodein = Kodein {
    extend(appKodein())

    bind<MyManager>(overrides = true) with singleton { mock<MyManager>() }
}
Run Code Online (Sandbox Code Playgroud)

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


dav*_*ber 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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