问题描述
我正在使用AS 3.4.1和运行Android 9的模拟器进行测试.
I'm testing with AS 3.4.1 and Emulator running Android 9.
当我在其中使用Room Dao Function annotated with @Transaction
时,以下测试将无法运行.
The following test won't run, when I use a Room Dao Function annotated with @Transaction
in it.
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()
}
}
这是用于插入的功能:
@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
}
因此,如果我按原样运行测试(请参见BreakPoint#1),则Breakpoint#2甚至都不会被调用,因此测试在某个地方结束,没有结果.
So if I'm running the test like it is (see BreakPoint #1), BreakPoint #2 won't even be called, so the test ends somewhere before, without a result.
如果我用完全相同的代码替换BreakPoint#1处的代码,则insert
函数具有该功能,则测试可以正确运行.
If I'm replacing the code at BreakPoint #1 with exact the same code, the insert
function has, the test runs correctly.
有人知道这里有什么问题吗?
Does anyone have an idea what's the issue here?
推荐答案
您可以使用 setTransactionExecutor 在另一个线程中运行事务
You can use setTransactionExecutor to run transaction in another thread
return Room
.inMemoryDatabaseBuilder(context, MyRoomDatabase::class.java)
.setTransactionExecutor(Executors.newSingleThreadExecutor())
.build()
然后在测试时使用 runBlocking 而不是runBlockingTest
then while testing use runBlocking instead of runBlockingTest
@Test
fun moveItem() = runBlocking {
transactionFunction()
}
这篇关于使用Room @Transaction函数时,Android工具测试不会结束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!