android Test Room + Paging 3 +Flow test 每次运行都有不同的结果 [英] android Test Room + Paging 3 +Flow test has different result on each run

查看:47
本文介绍了android Test Room + Paging 3 +Flow test 每次运行都有不同的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

分页 3,带房间.我已经创建了一个类似于示例 here 的应用程序并开始为它编写测试.

Paging 3, with Room. I have created an app just like the sample here and start writing test for it.

这是我在 DAO 中的内容:

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

我想像这样测试它:

@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?) {}
    }
}

与示例中的测试完全一样.奇怪的是,当我多次运行测试时,有些通过了,有些没有(说不同的.snapshot()是空的)当我在此文件中有几个其他测试(测试更新和删除)并尝试一起运行整个测试时,也会发生这种情况,有些通过,有些不通过,每轮通过的测试都不同.

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.

这就是我在 ViewModel 中用于获取列表的内容:

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)

一切都像示例一样,但不知道为什么会发生这种行为.我看到了其他帖子,例如 this 这正是我在测试中所做的,但我仍然遇到同样的问题.我应该提到的是,当我尝试在没有 PagingSource 返回类型的情况下测试如下查询时::

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.

推荐答案

我相信你需要等待失效发生,这是通过 InvalidationTracker 在插入时从 Room 的末端触发的.

I believe you need to wait for invalidation to happen, which is triggered via InvalidationTracker from Room's end on insert.

Room 默认使用 ArchTaskExecutors,您可以通过 RoomDatabase Builder 覆盖它或与有用的 InstantTaskExecutorRule

Room uses the ArchTaskExecutors by default, which you can override via RoomDatabase Builder or make synchronous with the helpful InstantTaskExecutorRule

@get:Rule
val instantRule = InstantTaskExecutorRule()

这篇关于android Test Room + Paging 3 +Flow test 每次运行都有不同的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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