Android Paging3:如何测试返回Pager的Repository并断言PagingData内容
测试Paging3 Repository中PagingData的内容数量
我已经实现了基于Android Paging3库的Repository,想测试自己的Repository实现。虽然看过官方的Paging3测试文档,但里面只有理论内容。
我的Repository代码如下:
class RepositoriesRepositoryImpl @Inject constructor( @IoCoroutineDispatcher private val ioCoroutineDispatcher: CoroutineDispatcher, private val service: GithubService, private val database: RepositoriesDatabase ) : RepositoriesRepository { @OptIn(ExperimentalPagingApi::class) override suspend fun fetchRepositories() = withContext(ioCoroutineDispatcher) { return@withContext Pager(config = PagingConfig( pageSize = NETWORK_PAGE_SIZE, enablePlaceholders = false ), remoteMediator = GithubRemoteMediator(ioCoroutineDispatcher, service, database), pagingSourceFactory = { database.repositoriesDao().allRepositories() }).flow } companion object { const val NETWORK_PAGE_SIZE = 10 } }
我的测试类代码如下:
@ExperimentalCoroutinesApi class RepositoriesRepositoryTest { private lateinit var sut: RepositoriesRepository private val testDispatcher = UnconfinedTestDispatcher() private val fakeGithubService: GithubService = mock { onBlocking { fetchRepos(any(), any()) } doSuspendableAnswer { Response.success((listOf())) } } private val inMemoryDatabase = Room.inMemoryDatabaseBuilder( ApplicationProvider.getApplicationContext(), RepositoriesDatabase::class.java ).build() @Before fun setup() { sut = RepositoriesRepositoryImpl(testDispatcher, fakeGithubService, inMemoryDatabase) } @Test fun test1() = runTest { sut.fetchRepositories().test { val item: PagingData<Repository> = awaitItem() assertNull(item) } } }
现在我希望断言PagingData的内容,验证其中是否包含预期数量的Repository数据,请问该如何实现?
解决方案
要断言PagingData中的内容数量,核心是将流式的PagingData转换为可直接操作的普通列表,同时需正确模拟依赖并触发完整的数据加载流程,具体实现如下:
1. 模拟返回预期数量的测试数据
修改FakeGithubService的Mock逻辑,生成指定数量的模拟Repository对象,为断言提供基础数据:
private val fakeGithubService: GithubService = mock { onBlocking { fetchRepos(any(), any()) } doSuspendableAnswer { // 生成10条模拟数据,与Repository中定义的NETWORK_PAGE_SIZE一致 val testRepos = List(10) { index -> Repository( id = index.toLong(), name = "TestRepo_$index", // 补充Repository类所需的其他必填字段 ) } Response.success(testRepos) } }
2. 借助Paging测试工具转换PagingData
Paging3提供了专门的测试库,可通过snapshot()方法快速将PagingData转换为包含所有加载数据的快照列表:
首先添加测试依赖(版本需与你的Paging3主库版本一致):
androidTestImplementation "androidx.paging:paging-testing:3.2.1"
然后修改测试方法:
@OptIn(ExperimentalCoroutinesApi::class) @Test fun fetchRepositories_returnsExpectedItemCount() = runTest(testDispatcher) { // 获取第一页PagingData val pagingData = sut.fetchRepositories().first() // 将PagingData转换为快照列表 val loadedItems = pagingData.snapshot().items // 断言数据数量符合预期 assertEquals(10, loadedItems.size) }
3. 手动收集PagingData内容(无需额外依赖)
如果不想引入测试库,可通过嵌套collect操作手动收集PagingData中的所有项:
@OptIn(ExperimentalCoroutinesApi::class) @Test fun fetchRepositories_returnsExpectedItemCount() = runTest(testDispatcher) { val collectedItems = mutableListOf<Repository>() sut.fetchRepositories().collect { pagingData -> pagingData.collect { repo -> collectedItems.add(repo) } } // 断言收集到的数据数量符合预期 assertEquals(10, collectedItems.size) }
4. 完善测试生命周期
为避免测试数据污染,在每个测试结束后关闭内存数据库:
@After fun teardown() { inMemoryDatabase.close() }
内容的提问来源于stack exchange,提问作者noloman
相关产品推荐
相关产品推荐

