4

我们有一个 Android 应用程序使用 compose 作为视图层,并且我们使用 Kodein 进行所有依赖注入。

我有一个 DIAware BaseApplication 类:

class BaseApplication : Application(), DIAware {
    override val di: DI = DI.lazy {
        import(modules) // modules defined in respective packages
    }
}

我还有一个 MainActivity 和一个导航图来管理各种可组合项之间的导航。

问题:如何在 MainActivity 的检测测试中正确覆盖这些模块?

@RunWith(AndroidJUnit4::class)
class MainActivityTest {
    @get:Rule
    val composeTestRule = createAndroidComposeRule<MainActivity>()

    val moduleOverrides = DI.Module(allowSilentOverride = true) {
        // add bindings for fakes w/ allowOverride = true
    }
    
    @Before
    fun setup() {
        val application =
            ApplicationProvider.getApplicationContext() as BaseApplication

        // how can I override the BaseApplication modules for my test?
    }

}

我似乎找不到任何关于此事的明确语言,并且觉得我遗漏了一些非常明显的东西。任何帮助将不胜感激。

4

1 回答 1

2

有几种方法可以实现这一目标。一般的方法是覆盖实际的模块,如

val someParrentKodeinModule...

val mockModule = Kodein {
    extend(someParrentKodeinModule, allowOverride = true)
    bind<Foo>(overrides = true) with provider { Foo2() }
}

or 

val kodein = Kodein {
    /* ... */
    import(testsModule, allowOverride = true)
}

哪里testsModule有一些模块已经定义了所有需要的模拟组件,这些组件将在主组件中被覆盖。你的方法也不错。关键是用所需的 DI 替换您的 DI - 这可以通过在您的应用程序中创建 DI 来完成 -var而不是val为其分配新值。但你将不得不放弃DIAware

class BaseApplication : Application() {
    var di: DI = DI.lazy {
        import(modules) // modules defined in respective packages
    }
}

@Before
    fun setup() {
        val application =
            ApplicationProvider.getApplicationContext() as BaseApplication

       application.di = moduleOverrides
    }

类似的东西。

并且一般不建议在 App 类中对应用使用单个 DI。为您要测试的应用程序的每个组件使用专门的模块

于 2021-11-30T16:26:52.320 回答