How To Test PagingData From Paging 3

痴心易碎 提交于 2021-01-29 09:11:11

问题


My ViewModel has a method which returns a flow of PagingData. In my app, the data is fetched from the remote server, which is then saved to Room (the single source of truth):

fun getChocolates(): Flow<PagingData<Chocolate>> {
    val pagingSourceFactory = { dao().getChocolateListData() }
    return Pager(
        config = PagingConfig(
            pageSize = NETWORK_PAGE_SIZE,
            maxSize = MAX_MEMORY_SIZE,
            enablePlaceholders = false
        ),
        remoteMediator = ChocolateRemoteMediator(
                api,
                dao
        ),
        pagingSourceFactory = pagingSourceFactory
    ).flow
}

How do I test this method? I want to test if the returning flow contains the correct data.

What I've tried so far:

@InternalCoroutinesApi
@Test
fun getChocolateListReturnsCorrectData() = runBlockingTest {
    val dao: Dao by inject()
    val viewModel: ViewModel by inject()

    // 1
    val chocolate1 = Chocolate(
        name = "Dove"
    )
    val chocolate2 = Chocolate(
        name = "Hershey's"
    )
    // 2
    dao.saveChocolate(chocolate1, chocolate2)
    // 3
    val pagingSourceFactory = { dao.getChocolateListData() }
    val pagingData = Pager(
        config = PagingConfig(
            pageSize = 50,
            maxSize = 200,
            enablePlaceholders = false
        ),
        pagingSourceFactory = pagingSourceFactory
    ).flow.collectLatest {

    }
    viewModel.getChocolates().collectLatest {

    }
    // 4

}

I'm wondering if I'm on the right track. Any help would be greatly appreciated!


回答1:


There's basically two approaches to this depending on if you want pre-transformation or post-transformation data.

If you want to just assert the repository end, that your query is correct - you can just query PagingSource directly, this is pre-transform though so any mapping you do or filtering you do to PagingData in ViewModel won't be accounted for here. However, it's more "pure" if you want to test the query directly.

@Test
fun repo() = runBlockingTest {
  val pagingSource = MyPagingSource()
  val loadResult = pagingSource.load(...)
  assertEquals(
    expected = LoadResult.Page(...),
    actual = loadResult,
  )
}

The other way if you care about transforms, you need to load data from PagingData into a presenter API.

@Test
fun ui() = runBlockingTest {
  val viewModel = ... // Some AndroidX Test rules can help you here, but also some people choose to do it manually.
  val adapter = MyAdapter(..)

  // You need to launch here because submitData suspends forever while PagingData is alive
  val job = launch {
    viewModel.flow.collectLatest {
      adapter.submitData(it)
    }
  }

  ... // Do some stuff to trigger loads
  advanceUntilIdle() // Let test dispatcher resolve everything

  // How to read from adapter state, there is also .peek() and .itemCount
  assertEquals(..., adapter.snapshot())

  // We need to cancel the launched job as coroutines.test framework checks for leaky jobs
  job.cancel()
}


来源:https://stackoverflow.com/questions/65810968/how-to-test-pagingdata-from-paging-3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!