如何在MainActivity的Android Instrumented测试中正确重写Kodein模块
方案1:修改BaseApplication支持动态覆写(无需自定义测试Application,推荐)
首先调整生产环境的BaseApplication代码,让di支持扩展覆写:
class BaseApplication : Application(), DIAware { // 将di改为可修改,保留原有初始化逻辑 override var di: DI = DI.lazy { import(modules) // modules defined in respective packages } private set // 对外暴露测试专用的覆写入口 fun overrideTestModules(vararg testModules: DI.Module) { // 以原有DI为基础扩展,开启覆写权限 di = DI { extend(di, allowOverride = true) importAll(*testModules) } } }
接下来修改测试代码,注意要关闭Compose测试规则的自动启动Activity逻辑,避免di在覆写前就被初始化:
@RunWith(AndroidJUnit4::class) class MainActivityTest { @get:Rule // 关闭默认自动启动Activity val composeTestRule = createAndroidComposeRule<MainActivity>( activityClass = MainActivity::class.java, launchActivity = false ) val moduleOverrides = DI.Module(allowSilentOverride = true) { // 在这里添加测试用的假实现绑定 } @Before fun setup() { val application = ApplicationProvider.getApplicationContext() as BaseApplication // 先覆写模块 application.overrideTestModules(moduleOverrides) // 覆写完成后再启动Activity composeTestRule.launchActivity() } }
方案2:自定义测试Application(无需修改生产代码)
如果不希望改动生产环境的BaseApplication,可以在androidTest源码目录下新建测试专用的Application类,直接覆写DI逻辑:
class TestBaseApplication : BaseApplication() { override val di: DI = DI.lazy { import(modules) // 直接导入覆盖模块,开启覆写权限 import(moduleOverrides, allowOverride = true) } }
之后在androidTest目录的AndroidManifest.xml中注册这个测试Application即可:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <application android:name=".TestBaseApplication" tools:replace="android:name" /> </manifest>
该方案适合所有测试用例共用同一套假实现的场景。
核心注意点
- 所有模块覆写操作必须在任何业务代码访问
di之前执行,因为懒加载的DI一旦完成初始化,后续修改不会生效 - 覆写模块必须开启覆写权限,否则Kodein会抛出绑定冲突异常
内容的提问来源于stack exchange,提问作者Maurycy
相关产品推荐
相关产品推荐

