使用KodeIn进行Android仪器化测试

4

我们有一个使用Compose作为视图层和Kodein作为所有依赖注入的Android应用程序。

我有一个BaseApplication类,它是DIAware:

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?
    }

}

我似乎找不到任何明确的语言来说明这个问题,感觉自己错过了一些非常显而易见的东西。非常感谢任何帮助。


我已经成功地使用ConfigurableDI插件使其工作。这是最好的选择吗? - Maurycy
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(依赖注入)。应为您想要测试的应用程序的每个组件使用专门的模块。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接