Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何用Mockk用transaction方法模拟android房间_Android_Kotlin_Android Room_Kotlin Coroutines_Mockk - Fatal编程技术网

如何用Mockk用transaction方法模拟android房间

如何用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

我正在尝试对我的业务逻辑进行一些单元测试。 我有一个存储库,其中保存了来自response的一些数据到room数据库(2.1.0-rc01)。 在单个事务中将数据保存到具有不同dao的不同表中。 代码简化为:

ItemRepository

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()
    }
}