the*_*ani 7 android kotlin android-room android-architecture-components kotlin-coroutines
我正在使用 AS 3.4.1 和运行 Android 9 的模拟器进行测试。
当我Room Dao Function annotated with @Transaction在其中使用 a 时,以下测试将无法运行。
class RecurrenceManagerTest : DatabaseTest() {
@Rule
@JvmField
val instantTaskExecutorRule = InstantTaskExecutorRule()
var recurringEntryId: Long = -1
@Before
override fun setup() {
super.setup() // only initialized the db
val recurringEntry = RecurringEntry(
recurrence = Recurrence(DATE.toEpochMilli(), Recurrence.DAILY)
)
recurringEntryId = runBlocking { db.recurringEntryDao().insert(recurringEntry) }
val recurringBookEntry = BookEntry.create(
title = TITLE,
date = DATE,
value = VALUE,
isPaid = IS_PAID,
notes = NOTES,
entryType = ENTRY_TYPE,
categoryId = CATEGORY_ID,
contacts = CONTACTS,
recurringEntryId = recurringEntryId
)
runBlocking {
db.bookEntryDao().insert(recurringBookEntry) // BreakPoint #1
}
}
@Test
fun testInsertRecurrencesAndSchedule() {
var recurringEntry = runBlocking { db.recurringEntryDao().get(recurringEntryId) } // BreakPoint #2
assertThat(recurringEntry, notNullValue())
runBlocking { RecurrenceManager.insertRecurrencesAndSchedule(ApplicationProvider.getApplicationContext(), db, recurringEntry!!) }
val bookEntries = db.bookEntryDao().getBookEntries().liveDataValue()
}
}
Run Code Online (Sandbox Code Playgroud)
这是插入的函数:
@Transaction
suspend fun insert(bookEntry: BookEntry): Long {
val id = insert(bookEntry.entity)
bookEntry.embeddedContacts?.apply {
forEach {
it.id = 0
it.bookEntryId = id
}
}?.let {
insert(it)
}
return id
}
Run Code Online (Sandbox Code Playgroud)
因此,如果我像这样运行测试(参见 BreakPoint #1),BreakPoint #2 甚至不会被调用,所以测试在某个地方之前结束,没有结果。
如果我用完全相同的代码替换 BreakPoint #1 处的代码,则该insert函数具有,测试运行正确。
有谁知道这里有什么问题?
sum*_*tta 19
您可以使用setTransactionExecutor在另一个线程中运行事务
return Room
.inMemoryDatabaseBuilder(context, MyRoomDatabase::class.java)
.setTransactionExecutor(Executors.newSingleThreadExecutor())
.build()
Run Code Online (Sandbox Code Playgroud)
然后在测试时使用runBlocking而不是 runBlockingTest
@Test
fun moveItem() = runBlocking {
transactionFunction()
}
Run Code Online (Sandbox Code Playgroud)
我遇到了同样的问题,问题是因为InstantTaskExecutorRule,如果删除下面的代码块,@Transaction应该可以很好地使用suspend关键字
@Rule
@JvmField
val instantTaskExecutorRule = InstantTaskExecutorRule()
Run Code Online (Sandbox Code Playgroud)
看来这个规则阻止了RoomDatabase获取事务线程。在RoomDatabase.kt执行过程中,以下函数被阻止:
private suspend fun Executor.acquireTransactionThread(controlJob: Job): ContinuationInterceptor
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
1314 次 |
| 最近记录: |