如何解决在Android单元测试中,从PagingData对象检查数据的正确方法是什么
我正在使用分页库从api检索数据并将它们显示在列表中
为此,我在存储库中创建了方法:
fun getArticleList(query: String): Flow<PagingData<ArticleHeaderData>>
在我的视图模型中,我创建了搜索方法,其内容如下:
override fun search(query: String) {
val lastResult = articleFlow
if (query == lastQuery && lastResult != null)
return
lastQuery = query
searchJob?.cancel()
searchJob = launch {
val newResult: Flow<PagingData<ArticleList>> = repo.getArticleList(query)
.map {
it.insertSeparators { //code to add separators }.cachedIn(this)
articleFlow = newResult
newResult.collectLatest {
articleList.postValue(it)
}
}
}
为了测试我的视图模型,我正在使用测试方法PagingData.from
来创建要从我的模拟存储库返回的流,如下所示:
whenever(repo.getArticleList(query)).thenReturn(flowOf(PagingData.from(articles)))
然后我从articleList LiveData检索实际的分页数据,如下所示:
val data = vm.articleList.value!!
这将返回一个PagingData<ArticleList>
对象,我想验证它是否包含来自服务的数据(即无论何时返回的articles
)
我发现这样做的唯一方法是创建以下扩展功能:
private val dcb = object : DifferCallback {
override fun onChanged(position: Int,count: Int) {}
override fun onInserted(position: Int,count: Int) {}
override fun onRemoved(position: Int,count: Int) {}
}
suspend fun <T : Any> PagingData<T>.collectData(): List<T> {
val items = mutableListOf<T>()
val dif = object : PagingDataDiffer<T>(dcb,TestDispatchers.Immediate) {
override suspend fun presentNewList(previousList: NullPaddedList<T>,newList: NullPaddedList<T>,newCombinedLoadStates: CombinedLoadStates,lastAccessedIndex: Int): Int? {
for (idx in 0 until newList.size)
items.add(newList.getFromStorage(idx))
return null
}
}
dif.collectFrom(this)
return items
}
似乎有效,但是基于标记为PagingDataDiffer
的{{1}}类,因此将来可能无法使用
是否有更好的方法从PagingData(在库中标记为内部)获取@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
或从中获取实际数据?
解决方法
我在Paging3库中遇到了同样的问题,关于这个库的在线讨论还不多,但是当我深入研究一些文档时,可能会找到一个解决方案。我面临的场景是尝试确定PagingData
中的数据列表是否为空,然后我将基于此操作UI。
这是我在文档中找到的内容,在PagingDataAdapter
中添加了两个API,版本为peek()
,版本为snapshot()
,而peek()
是{{1 }}为我们提供了一个基于索引的特定列表对象,而snapshot()
为我们提供了整个列表。
这就是我所做的:
lifecycleScope.launch {
//Your PagingData flow submits the data to your RecyclerView adapter
viewModel.allConversations.collectLatest {
adapter.submitData(it)
}
}
lifecycleScope.launch {
//Your adapter's loadStateFlow here
adapter.loadStateFlow.
distinctUntilChangedBy {
it.refresh
}.collect {
//you get all the data here
val list = adapter.snapshot()
...
}
}
由于我刚开始使用Paging库和Flow
,因此这种方法可能存在缺陷,请让我知道是否有更好的方法!
这仅在有活动的互联网连接时有效。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。