如何在Ktor中mock KMongo的CoroutineDatabase?Koin模块中如何实现?
实现方案
失败原因
你之前的两种写法都仅实例化了mock的CoroutineClient,但没有对getDatabase方法的返回值进行打桩配置,调用后只会返回默认空值/null,注入到业务代码后调用相关方法就会报错。
方案1:基于Mockito实现(适合纯Mockito技术栈)
如果你的业务代码仅直接注入CoroutineDatabase实例,不需要依赖CoroutineClient,可以直接mock目标类,Koin模块配置如下:
val testModule = module { single<CoroutineDatabase> { Mockito.mock(CoroutineDatabase::class.java) } }
如果业务中同时需要用到CoroutineClient,则需要对Client的方法调用打桩:
val testModule = module { single<CoroutineClient> { val mockDb = Mockito.mock(CoroutineDatabase::class.java) val mockClient = Mockito.mock(CoroutineClient::class.java) // 对getDatabase方法打桩,返回我们的mock数据库实例 Mockito.`when`(mockClient.getDatabase(CoreConstants.DATABASE_NAME)) .thenReturn(mockDb) mockClient } single<CoroutineDatabase> { get<CoroutineClient>().getDatabase(CoreConstants.DATABASE_NAME) } }
方案2:基于Koin Test + MockK实现(适合Kotlin技术栈)
如果使用Koin Test模块的declareMock API,需要显式配置方法的返回规则:
startKoin { modules(yourBaseTestModule) // 先声明mock的数据库实例 val mockDb = declareMock<CoroutineDatabase>() // 声明mock的Client,配置getDatabase的返回值 declareMock<CoroutineClient> { every { getDatabase(CoreConstants.DATABASE_NAME) } returns mockDb } // 对外提供Database实例 single<CoroutineDatabase> { get<CoroutineClient>().getDatabase(CoreConstants.DATABASE_NAME) } }
后续可以基于mock的CoroutineDatabase继续打桩集合、查询等方法的返回值,适配业务测试需求。
注意事项
- 若使用Mockito,需开启final类mock支持:在
src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker文件中添加内容mock-maker-inline,否则无法mock KMongo的final类 - 业务中用到的数据库集合、CRUD方法都需要对应打桩返回mock结果,否则调用时会返回默认空值
内容的提问来源于stack exchange,提问作者Vahid Garousi
相关产品推荐
相关产品推荐

