gpt4 book ai didi

android - 如何从 Paging 3 测试 PagingData

转载 作者:行者123 更新时间:2023-12-04 03:42:09 26 4
gpt4 key购买 nike

我的 ViewModel 有一个返回 PagingData 流的方法。在我的应用程序中,数据是从远程服务器获取的,然后保存到 Room(单一真实来源):

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
}

如何测试此方法?我想测试返回的流是否包含正确的数据。

到目前为止我尝试了什么:

@InternalCoroutinesApi
@Test
fun getChocolateListReturnsCorrectData() = runBlockingTest {
val chocolateListDao: ChocolateListDao by inject()
val chocolatesRepository: ChocolatesRepository by inject()
val chocolateListAdapter: ChocolateListAdapter by inject()

// 1
val chocolate1 = Chocolate(
name = "Dove"
)
val chocolate2 = Chocolate(
name = "Hershey's"
)

// 2
// You need to launch here because submitData suspends forever while PagingData is alive
val job = launch {
chocolatesRepository.getChocolateListStream().collectLatest {
chocolateListAdapter.submitData(it)
}
}

// Do some stuff to trigger loads
chocolateListDao.saveChocolate(chocolate1, chocolate2)

// How to read from adapter state, there is also .peek() and .itemCount
assertEquals(listOf(chocolate1, chocolate2).toMutableList(), chocolateListAdapter.snapshot())

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

我想知道我是否在正确的轨道上。任何帮助将不胜感激!

最佳答案

我发现使用 Turbine from cashapp会容易得多。( JakeWharton 再次来救援 :P)

testImplementation "app.cash.turbine:turbine:0.2.1"

根据您的代码,我认为您的测试用例应该如下所示:

@ExperimentalTime
@ExperimentalCoroutinesApi
@Test
fun `test if receive paged chocolate data`() = runBlockingTest {

val expected = listOf(
Chocolate(name = "Dove"),
Chocolate(name = "Hershey's")
)

coEvery {
dao().getChocolateListData()
}.returns(
listOf(
Chocolate(name = "Dove"),
Chocolate(name = "Hershey's")
)
)

launchTest {
viewModel.getChocolates().test(
timeout = Duration.ZERO,
validate = {
val collectedData = expectItem().collectData()
assertEquals(expected, collectedData)
expectComplete()
})
}
}

我还准备了一个基本的 ViewModelTest 类来处理大部分设置和拆卸任务:

abstract class BaseViewModelTest {
@get:Rule
open val instantTaskExecutorRule = InstantTaskExecutorRule()

@get:Rule
open val testCoroutineRule = CoroutineTestRule()

@MockK
protected lateinit var owner: LifecycleOwner

private lateinit var lifecycle: LifecycleRegistry

@Before
open fun setup() {
MockKAnnotations.init(this)

lifecycle = LifecycleRegistry(owner)
every { owner.lifecycle } returns lifecycle
}

@After
fun tearDown() {
clearAllMocks()
}

protected fun initCoroutine(vm: BaseViewModel) {
vm.apply {
setViewModelScope(testCoroutineRule.testCoroutineScope)
setCoroutineContext(testCoroutineRule.testCoroutineDispatcher)
}
}

@ExperimentalCoroutinesApi
protected fun runBlockingTest(block: suspend TestCoroutineScope.() -> Unit) =
testCoroutineRule.runBlockingTest(block)


protected fun launchTest(block: suspend TestCoroutineScope.() -> Unit) =
testCoroutineRule.testCoroutineScope.launch(testCoroutineRule.testCoroutineDispatcher) { block }

}

至于从answer from another post 借来的扩展函数collectData() (感谢 @Farid !!)

还有介绍turbine的幻灯片

关于android - 如何从 Paging 3 测试 PagingData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65810968/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com