Paging 3, with Room. I have created an app just like the sample here and start writing test for it.
Here is what I have in DAO :
@Query("SELECT * FROM Model")
fun getModels(): PagingSource<Int, Model>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(list: MutableList<Model>) : Completable
and I wanted to test it like this:
@OptIn(ExperimentalCoroutinesApi::class)
class DAOTest {
private lateinit var dao: Dao
private lateinit var db: ModelDatabase
private lateinit var viewModel: MyViewModel
lateinit var context: Context
private val testDispatcher = TestCoroutineDispatcher()
@Before
fun createDb() {
Dispatchers.setMain(testDispatcher)
context = InstrumentationRegistry.getInstrumentation().targetContext
db = Room.inMemoryDatabaseBuilder(context, MyDatabase::class.java)
.allowMainThreadQueries()
.build()
dao = db.Dao()
viewModel =
MyViewModel(MyRepository(db))
}
@After
fun tearDown() {
Dispatchers.resetMain()
db.close()
}
@Test
fun dataBase_insertAndGet_success() = runBlockingTest(testDispatcher) {
val differ = AsyncPagingDataDiffer(
MyAdapter.diffCallback,
noopListUpdateCallback,
testDispatcher,
testDispatcher
)
dao.insertAll(
mutableListOf(listOfModels)
).test().assertResult()
val job = launch {
viewModel.getList().collectLatest {
differ.submitData(it)
}
}
advanceUntilIdle()
Truth.assertThat(differ.snapshot()).containsExactly(
model1, model2,model3,model4)
job.cancel()
}
private val noopListUpdateCallback = object : ListUpdateCallback {
override fun onInserted(position: Int, count: Int) {}
override fun onRemoved(position: Int, count: Int) {}
override fun onMoved(fromPosition: Int, toPosition: Int) {}
override fun onChanged(position: Int, count: Int, payload: Any?) {}
}
}
Exactly like the test in the sample. Strange think is that when I run the test several times some is passing and some not(saying the differ.snapshot() is empty) This is happening too when I have several other tests in this file (testing updating and removing) and try to run the whole tests together, some passing and some not which the passing tests are different in each round.
and this is what I have in my ViewModel for getting the list:
fun getList(type: Int, search: String? = null): Flow<PagingData<Stock>> {
return Pager(
config = PagingConfig(
pageSize = PAGE_SIZE,
enablePlaceholders = true,
maxSize = MAX_SIZE
)
) {
repository.getListFromDao()
}.flow
.cachedIn(viewModelScope)
everything is like the sample but don't know why this behavior is happening. I saw other posts like this which is exactly what I have done in my test, but still I have the same problem. I should mention that when I try to test a query like below without the returning type of PagingSource<Int, Model> :
@Query("SELECT * FROM Model")
fun getModels(): List<Model>
everything works fine. the test passes every time I run it. so I think there is something wrong with this part in the test:
val job = launch {
viewModel.getList().collectLatest {
differ.submitData(it)
}
}
Will really happy if anyone could help and give some hints, since I am working on it for quite a long time. Thank you.