KMM中Room DAO跨端测试:避免重复及Context适配方案
在KMM中共享Room DAO测试代码的解决方案
核心思路
借助Kotlin的expect/actual机制延伸到测试模块,让平台侧各自实现内存数据库的初始化逻辑,通用测试代码直接调用统一接口,彻底避免测试代码重复。
步骤1:在通用测试模块定义预期接口
在commonTest源码目录下创建数据库测试工厂的expect声明:
// commonTest/kotlin/com/yourpackage/db/DbTestFactory.kt expect object DbTestFactory { fun createInMemoryDb(): YourAppDatabase }
步骤2:Android测试模块实现actual
在androidTest中利用测试上下文初始化内存数据库,通过InstrumentationRegistry获取Context:
// androidTest/kotlin/com/yourpackage/db/DbTestFactory.kt actual object DbTestFactory { actual fun createInMemoryDb(): YourAppDatabase { val context = InstrumentationRegistry.getInstrumentation().targetContext return Room.inMemoryDatabaseBuilder(context, YourAppDatabase::class.java) .allowMainThreadQueries() // 测试环境下简化代码,允许主线程操作 .build() } }
步骤3:iOS测试模块实现actual
在iosTest中直接初始化内存数据库(Room在iOS端基于SQLite实现,无需Context):
// iosTest/kotlin/com/yourpackage/db/DbTestFactory.kt actual object DbTestFactory { actual fun createInMemoryDb(): YourAppDatabase { return Room.inMemoryDatabaseBuilder(null, YourAppDatabase::class.java) .allowMainThreadQueries() .build() } }
步骤4:编写通用DAO测试
在commonTest中编写一次测试代码,直接调用工厂类获取数据库,所有测试逻辑完全共享:
// commonTest/kotlin/com/yourpackage/db/YourDaoTest.kt class YourDaoTest { private lateinit var db: YourAppDatabase private lateinit var dao: YourDao @BeforeTest fun setup() { db = DbTestFactory.createInMemoryDb() dao = db.yourDao() } @AfterTest fun teardown() { db.close() } @Test fun `insert item should return correct id`() { val testItem = TestItem(name = "test") val id = dao.insert(testItem) assertEquals(1, id) } // 其他测试用例... }
关键注意事项
allowMainThreadQueries()仅用于测试环境简化代码,生产环境务必移除。- 确保
YourAppDatabase的实体、DAO定义都在通用代码中,平台侧只负责初始化逻辑。 - Android端通过Instrumented Tests执行测试,iOS端通过Xcode或KMM测试任务执行,逻辑完全复用。
内容的提问来源于stack exchange,提问作者David Gonçalves
相关产品推荐
相关产品推荐

