【发布时间】:2021-06-13 10:42:58
【问题描述】:
第 3 页,带房间。 我已经创建了一个类似于示例here 的应用程序并开始为其编写测试。
这是我在 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)
一切都像示例,但不知道为什么会发生这种行为。
我看到了像this 这样的其他帖子,这正是我在测试中所做的,但我仍然遇到同样的问题。
我应该提到,当我尝试在没有返回 PagingSource
@Query("SELECT * FROM Model")
fun getModels(): List<Model>
一切正常。每次我运行它时测试都会通过。所以我认为测试中这部分有问题:
val job = launch {
viewModel.getList().collectLatest {
differ.submitData(it)
}
}
如果有人可以提供帮助并提供一些提示,我将非常高兴,因为我已经为此工作了很长时间。 谢谢。
【问题讨论】:
-
在为 submitData 启动作业后插入是否有帮助?由于您没有使用暂停版本,因此我不确定 Paging 是否会在比赛中及时恢复失效
-
感谢您的评论。我做到了,没有不工作。这来自 android 文档:直接使用 PagingSource 类来使用 Kotlin 协程进行异步加载。所以它使用引擎盖下的暂停。在为differ.submitdata 提供午餐的示例中,它说:submitData 允许diff 从PagingData 接收数据,但会暂停直到失效,因此我们必须在单独的作业中启动它。想也许它有助于解决问题。不知道幕后发生了什么。
-
正如你所说,这似乎是因为不同。正如文档所说:“注意:submitData() 方法暂停并且在 PagingSource 无效或调用适配器的 refresh 方法之前不会返回。这意味着 submitData() 调用之后的代码可能比您预期的要晚得多。”并且当我在启动后调用differ.refresh() 多次运行测试时它是可以的,但是当我一起运行所有测试时,再次通过一些不通过,但单次运行是可以的。在断言之前不知道如何强制不同给我结果。
标签: android android-room android-testing android-paging-3 kotlin-coroutines