Skip to content Skip to sidebar Skip to footer

Android Instrumented Test Freezes When It Tests A Suspend Function That Uses Roomdatabase.withtransaction

I'm trying to test the following LocalDataSource function, NameLocalData.methodThatFreezes function, but it freezes. How can I solve this? Or How can I test it in another way? Clas

Solution 1:

Last time I wrote a test for Room database I just simply use runBlock and it worked for me... Could you take a look into this sample and check if it works for you as well?

Edit: Ops! I missed this part... I tried this (in the same sample):

  1. I defined a dummy function in my DAO using @Transaction
@TransactionsuspendfunquickInsert(book: Book) {
    save(book)
    delete(book)
}
  1. I think this is the key of the problem. Add setTransactionExecutor to your Database instantiation.
appDatabase = Room.inMemoryDatabaseBuilder(
    InstrumentationRegistry.getInstrumentation().context,
    AppDatabase::class.java
).setTransactionExecutor(Executors.newSingleThreadExecutor())
    .build()
  1. Finally, the test worked using runBlocking
@TestfundummyTest() = runBlocking {
    val dao = appDatabase.bookDao();
    val id = dummyBook.id

    dao.quickInsert(dummyBook)

    val book = dao.bookById(id).first()
    assertNull(book)
}

See this question.

Solution 2:

I had tried many things to make this work, used runBlockingTest, used TestCoroutineScope, tried runBlocking, used allowMainThreadQueries, setTransactionExecutor, and setQueryExecutor on my in memory database.

But nothing worked until I found this comment thread in the Threading models in Coroutines and Android SQLite API article in the Android Developers Medium blog, other people mentioned running into this. Author Daniel Santiago said:

I’m not sure what Robolectric might be doing under the hood that could cause withTransaction to never return. We usually don’t have Robolectric tests but we have plenty of Android Test examples if you want to try that route: https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingQueryTest.kt

I was able to fix my test by changing it from a Robolectric test to an AndroidTest and by using runBlocking

This is an example from the google source:

@Before@Throws(Exception::class)funsetUp() {
        database = Room.inMemoryDatabaseBuilder(
            ApplicationProvider.getApplicationContext(),
            TestDatabase::class.java
        )
            .build()
        booksDao = database.booksDao()
    }

    @TestfunrunSuspendingTransaction() {
        runBlocking {
            database.withTransaction {
                booksDao.insertPublisherSuspend(
                    TestUtil.PUBLISHER.publisherId,
                    TestUtil.PUBLISHER.name
                )
                booksDao.insertBookSuspend(TestUtil.BOOK_1.copy(salesCnt = 0))
                booksDao.insertBookSuspend(TestUtil.BOOK_2)
                booksDao.deleteUnsoldBooks()
            }
            assertThat(booksDao.getBooksSuspend())
                .isEqualTo(listOf(TestUtil.BOOK_2))
        }
    }

Post a Comment for "Android Instrumented Test Freezes When It Tests A Suspend Function That Uses Roomdatabase.withtransaction"