为什么 AsyncPagingDataDiffer submitData() 应该冻结和超时测试?

Why should AsyncPagingDataDiffer submitData() freeze and timeout the test?

我正在尝试关注 this documentation here 关于如何对应用转换的 PagingData 流进行单元测试。我使用的代码类似:

@ExperimentalCoroutinesApi
@Test
fun testGetFooBarsPaged(): Unit = runTest {
    val differ = AsyncPagingDataDiffer(
        object : DiffUtil.ItemCallback<FooBar>() {
            override fun areItemsTheSame(oldItem: FooBar, newItem: FooBar) = false
            override fun areContentsTheSame(oldItem: FooBar, newItem: FooBar) = false
        },
        object : ListUpdateCallback {
            override fun onChanged(position: Int, count: Int, payload: Any?) {}
            override fun onMoved(fromPosition: Int, toPosition: Int) {}
            override fun onInserted(position: Int, count: Int) {}
            override fun onRemoved(position: Int, count: Int) {}
        }
    )
    val pagingData = fooBarsSdk.getFooBarsPaged(FooBar.Type, pageSize = 1).first()
    differ.submitData(PagingData.from(listOf(FooBar(), FooBar(), FooBar())))
}

此处执行测试的最后两行,测试成功终止:

  1. getFooBarsPaged() 检索 Flow,我可以在其上调用 first() 并检索 PagingData 的第一个实例。
  2. 在下一行,您可以看到我还可以毫无问题地向我的 AsyncPagingDataDiffer 对象提交一些任意的 FooBar 对象列表。

问题是当我尝试将从 Flow 获取的 PagingData 实例提交给 AsyncPagingDataDiffer 对象时:differ.submitData(pagingData)。此调用会阻塞,直到 runTest() 在 60 秒后超时。我的问题是,为什么会这样?

Pager 对象和 Flow 是这样创建的:

Pager(
    config = PagingConfig(pageSize),
    initialKey = null,
    pagingSourceFactory = factory.asPagingSourceFactory(Dispatchers.Default)
).flow.map { pagingData -> pagingData.map { fooBarEntity -> fooBarEntity.toFooBar() } }

从 Room Dao 方法检索数据源工厂的位置,例如:

@Query("SELECT DISTINCT * FROM foobars WHERE type = :type")
fun getAllFooBarsByTypeLive(type: String): DataSource.Factory<Int, FooBarEntity>

以下作品在这里:

val job = launch {
        val pagingData = Pager(
            config = PagingConfig(20),
            initialKey = null,
            pagingSourceFactory = db.fooBarDao().getAllFooBarsByTypeLive("test")
                .asPagingSourceFactory()
        ).flow.map { pagingData -> pagingData.map { fooBarEntity -> fooBarEntity.toFooBar() } }
            .toList()[2]
        differ.submitData(pagingData)
    }
    job.cancel()

当然,您的流程中至少需要 3 个元素。 How To Test PagingData From Paging 3

原因

val pagingData = fooBarsSdk.getFooBarsPaged(FooBar.Type, pageSize = 1).first()
differ.submitData(PagingData.from(listOf(FooBar(), FooBar(), FooBar())))

有效的是您使用的是“来自”,然后您不需要启动,因为您可以在此处阅读 https://developer.android.com/topic/libraries/architecture/paging/test