ページングライブラリを使用してAPIからデータを取得してリストに表示しています。
この目的のために私のリポジトリのこの方法を作成しました。
fun getArticleList(query: String): Flow<PagingData<ArticleHeaderData>>
私のViewModelでは、このようなものになる検索方法を作成しました。
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)
}
}
}
my ViewModelをテストするには、テストメソッドPagingData.from
を使用して、My Mockedリポジトリから戻るフローを作成します。
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
}
これは働いているようですが、@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
とマークされているPagingDataDiffer
クラスに基づいているので、将来動作しないかもしれません
pagingData(ライブラリ内の内部としてマークされている)からflow
を取得するか、実際のデータを入手するためのより良い方法がありますか?
これはアクティブなインターネット接続がある場合にのみ機能します。