Hey, I am trying to test Android room Dao function...
# room
k
Hey, I am trying to test Android room Dao function that returns a PagingSource. But following the docs, the test runs indefinitely. Check the following snippet:
Copy code
val expectedData = listOf(area)

val expected = PagingSource.LoadResult.Page(
    data = expectedData,
    prevKey = null,
    nextKey = 1
)

val actual = globalAreaDao.fetchPagedGlobalAreas("%a%").load(
    PagingSource.LoadParams.Refresh(
        key = null,
        loadSize = 2,
        placeholdersEnabled = false
    )
)
Truth.assertThat(expected).isEqualTo(actual)
Is this the right way to test dao functions that return a
PagingSource
object?
y
is this using room - paging artifact ? (in 2.4) not sure why that is not working, cc: @dustin
k
Yes, I have finally resolved this. I had
InstantTaskExecutorRule
which caused the load function not return. Also, it fails using
runBlockingTest
on the
mainCoroutineRule
but works for
runBlocking
.
j
I'm running into the same issue with PagingSource
load
function not returning. This after updating to Room 2.4 (2.3 works fine). I had to @Ignore some existing tests. I tried above ☝️ solution but no luck so far.
On the dev comments https://android.googlesource.com/platform/frameworks/support/+/b0897a44f5ecc1bbfb66be98fccf03ef77bc5d90
Copy code
"The PagingSource implementation generated by room-paging now
  uses the queryExecutor passed through RoomDatabase.Builder, so it can
  be overridden, instead of <http://Dispatchers.IO|Dispatchers.IO> previously."
I had to change the executor back to
<http://Dispatchers.IO|Dispatchers.IO>.asExecutor()
to make the tests work like before.
Copy code
Room
          .inMemoryDatabaseBuilder(context, db)
          .allowMainThreadQueries()
          .setQueryExecutor(executor)
          .setTransactionExecutor(executor)
Additional note: I also tried using
StandardTestDispatcher().asExecutor()
which I believe is the replacement for the deprecated
TestCoroutineDispatcher()
but that did not work as well. cc: @yigit @dustin
y
What do you mean by "work like before"?
j
Hi @yigit, the tests on my project was working on Room v2.3. Changing only the dispatcher executor on my tests to Dispatchers.IO makes it pass on v2.4. In this setup, the executor was set to
Executors.newSingleThreadExecutor()
in Room 2.3 and the tests involving PgingSource
load
was working fine. In Room 2.4, these tests suddenly failed, the
load
function wasn't returning and causing the tests to take too long. Changing it
<http://Dispatchers.IO|Dispatchers.IO>.asExecutor()
made it pass again.
Copy code
Room
          .inMemoryDatabaseBuilder(context, db)
          .allowMainThreadQueries()
          .setQueryExecutor(executor)
          .setTransactionExecutor(executor)
y
If you pass the same executor to both read and write executors, it doesn't work with coroutines due to a conflict with android SQLite transactions (they are thread bound). As for that test, it probably passed because it was using the dispatchers io, I assume that's not what you would want especially if you were passing a special executor to room
j
Thank you @yigit. Switching to different executors between the read and write fixed the tests. Using
newSingleThreadExecutor
(write) and
TestCoroutineDispatcher
(read) as executor made it work for me.