0

第 3 页,带房间。我已经像这里的示例一样创建了一个应用程序,并开始为它编写测试。

这是我在 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?) {}
    }
}

与样本中的测试完全一样。奇怪的想法是,当我多次运行测试时,有些通过而有些没有(说differ.snapshot()是空的)当我在这个文件中有几个其他测试(测试更新和删除)并尝试一起运行整个测试,有些通过,有些不通过,每轮通过的测试都不同。

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

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)

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

@Query("SELECT * FROM Model")
fun getModels(): List<Model>

一切正常。每次我运行它时测试都会通过。所以我认为测试中这部分有问题:

val job = launch {
    viewModel.getList().collectLatest {
        differ.submitData(it)
    }
}

如果有人可以提供帮助并提供一些提示,我会非常高兴,因为我已经为此工作了很长时间。谢谢你。

4

1 回答 1

0

我相信您需要等待失效发生,这是InvalidationTracker在插入时从 Room 的末尾触发的。

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

@get:Rule
val instantRule = InstantTaskExecutorRule()
于 2021-06-15T00:46:11.410 回答