[英]How to Unit Test a Room Dao Query that Returns a PagingSource From Paging 3
我的问题实际上很笼统。 我想知道如何对从Paging 3返回PagingSource的Room Dao查询进行单元测试。
我有一个Room Dao查询:
@Query("SELECT * FROM database")
fun getChocolateListData(): PagingSource<Int, Chocolate>
我想知道如何对这个查询进行单元测试。
到目前为止我尝试过的(使用内存中的Room数据库进行测试):
@FlowPreview
@Test
fun saveChocolateToDbSavesData() = runBlocking {
val dao: Dao by inject()
val chocolate = Chocolate(
name = "Dove"
)
dao.saveChocolate(chocolate)
val pagingSourceFactory = { dao.getChocolateListData() }
val pagingDataFlow: Flow<PagingData<Chocolate>> = Pager(
config = PagingConfig(
pageSize = 50,
maxSize = 200,
enablePlaceholders = false
),
pagingSourceFactory = pagingSourceFactory
).flow
val chocolateListFlow = pagingDataFlow.testIn(coroutinesTestRule)
Assert.assertEquals(PagingData.from(listOf(chocolate)), chocolateListFlow.emissions[0])
}
然而,这并没有通过:
junit.framework.AssertionFailedError:预期:androidx.paging.PagingData@7d6c23a1 实际:androidx.paging.PagingData@321123d2
不知道如何正确处理。 任何帮助将不胜感激!
PagingData
是内部事件 stream 的包装,您无法直接比较它,并且您得到的错误是按预期抛出引用不等式。
相反,您应该直接查询PagingSource
以比较LoadResult.Page
中的数据,或者您需要将其连接到演示者 API,例如AsyncPagingDataDiffer
或PagingDataAdapter
并使用.snapshot()
val flow = Pager(..).flow
val adapter = MyPagingDataAdapter()
val job = launch {
flow.collectLatest { adapter.submitData(it) }
}
// Do your asserts here
job.cancel()
如果您需要测试 scope,我建议您使用runBlockingTest
库中的 runBlockingTest
要直接查询PagingSource
,它有一个暂停的.load()
方法,因此您可以简单地将其包装在runBlockingTest
中并断言结果:
@Test
fun test() = runBlockingTest {
val pagingSource = MyPagingSource()
val actual = pagingSource.load(LoadParams.Refresh(...))
assertEquals(actual as? LoadResult.Page)?.data, listOf(...))
}
以防万一您需要模拟 PagingSource:
创建助手 class PagingSourceUtils.kt 示例:
class PagingSourceUtils<T : Any>(
private val data: List<T>
) : PagingSource<Int, T>() {
override fun getRefreshKey(state: PagingState<Int, T>): Int? {
return 0
}
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, T> {
return LoadResult.Page(
data = data,
prevKey = null,
nextKey = null
)
}
}
你的测试.kt
@Test
fun `should success get Chocolate `() {
val chocolates = listOf(Chocolate(
name = "Dove"
))
runBlocking {
val tData = PagingSourceUtils(chocolates)
`when`(dao.getChocolateListData()).thenReturn(tData)
val data = ...
val actual = ..
assertEquals(actual, data)
}
}
根据标记为正确的答案,我自己做了,不是很漂亮,但如果有任何反馈我会很高兴,至少可以完成工作,在此先感谢。
fun <PaginationKey: Any, Model: Any>PagingSource<PaginationKey, Model>.getData(): List<Model> {
val data = mutableListOf<Model>()
val latch = CountDownLatch(1)
val job = CoroutineScope(Dispatchers.Main).launch {
val loadResult: PagingSource.LoadResult<PaginationKey, Model> = this@getData.load(
PagingSource.LoadParams.Refresh(
key = null, loadSize = Int.MAX_VALUE, placeholdersEnabled = false
)
)
when (loadResult) {
is PagingSource.LoadResult.Error -> throw loadResult.throwable
is PagingSource.LoadResult.Page -> data.addAll(loadResult.data)
}
latch.countDown()
}
latch.await()
job.cancel()
return data
}
所以在你的测试中,你可以像这样使用它
val obtainedData = myDao.getSomePagingSource().getData()
assertEquals(expectedData, obtainedData)
警告:你会看到一个相当长的日志
WARNING: pageSize on the LegacyPagingSource is not set.
When using legacy DataSource / DataSourceFactory with Paging3, page size...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.