如何用Mockk用transaction方法模拟android房间
我正在尝试对我的业务逻辑进行一些单元测试。 我有一个存储库,其中保存了来自response的一些数据到room数据库(2.1.0-rc01)。 在单个事务中将数据保存到具有不同dao的不同表中。 代码简化为: ItemRepository如何用Mockk用transaction方法模拟android房间,android,kotlin,android-room,kotlin-coroutines,mockk,Android,Kotlin,Android Room,Kotlin Coroutines,Mockk,我正在尝试对我的业务逻辑进行一些单元测试。 我有一个存储库,其中保存了来自response的一些数据到room数据库(2.1.0-rc01)。 在单个事务中将数据保存到具有不同dao的不同表中。 代码简化为: ItemRepository suspend fun saveItems(response: Response) { val items = response.items.map { it.toLocalItem() } val subItems = response.it
suspend fun saveItems(response: Response) {
val items = response.items.map { it.toLocalItem() }
val subItems = response.items.flatMap { item ->
item.subItems.map { it.toLocal(item.id) }
}
db.withTransaction {
db.itemDao().deleteAll()
db.itemDao().insertAll(items)
db.subItemDao().insertAll(subItems)
}
}
对于单元测试,我使用Mockk库。如何使用事务处理方法模拟房间?。withTransaction声明为
suspend fun <R> RoomDatabase.withTransaction(block: suspend () -> R): R
首先必须使用事务{}为Android Room KTX方法启用静态模拟。您还需要捕获传递给它的suspend lambda函数。可以调用此捕获的函数,使其内部的代码运行。因为您正在模拟所有数据库调用,所以这里不需要真正的事务
@Before
fun initMocks() {
MockKAnnotations.init(this)
mockkStatic(
"androidx.room.RoomDatabaseKt"
)
val transactionLambda = slot<suspend () -> R>()
coEvery { db.withTransaction(capture(transactionLambda)) } coAnswers {
transactionLambda.captured.invoke()
}
}
@之前
mocks()的乐趣{
MockKAnnotations.init(this)
模拟静电(
“androidx.room.RoomDatabaseKt”
)
val transactionLambda=插槽R>()
coEvery{db.withTransaction(capture(transactionLambda))}共同应答{
transactionLambda.captured.invoke()
}
}
然后,您应该能够按照编写的方式运行代码。要扩展Andrew的答案,说明如果您正在模拟对象范围或类范围的扩展函数,您可以使用常规的
mock
来实现这一点。但是,如果您使用的是模块范围的扩展功能,如with transaction
,则还需要对模块的类名执行mockkStatic
。谢谢,我正在尝试捕获,但在没有静态mock的情况下进行测试
@Before
fun initMocks() {
MockKAnnotations.init(this)
mockkStatic(
"androidx.room.RoomDatabaseKt"
)
val transactionLambda = slot<suspend () -> R>()
coEvery { db.withTransaction(capture(transactionLambda)) } coAnswers {
transactionLambda.captured.invoke()
}
}