使用Room @Transaction函数时,Android工具测试不会结束 [英] Android instrumentation test doesn't run to end when using Room @Transaction function

查看:747
本文介绍了使用Room @Transaction函数时,Android工具测试不会结束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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工具测试不会结束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆