Android测试中如何创建Foo对象的PagedList?
解决PagedList测试的两个问题:可行性与实例构造
针对你遇到的PagedList测试问题,我来一步步帮你梳理清楚:
1. 这种测试方式完全可行!
只要你能构造出合法的PagedList<Foo>测试实例,就可以用Mockito(或其他Mock框架)来Stub仓库的getFoos()方法,让它返回包含测试数据的Observable。这样ViewModel就能拿到模拟数据,你也能顺利完成端到端的UI验证,确认Fragment/Activity能正确显示Foo列表。
2. 如何创建测试用的PagedList
PagedList的构造需要依赖PagedList.Config和DataSource,下面提供两种实用的实现方式:
方法一:手动构造基础测试实例
首先定义测试用的Config,尽量和生产环境的配置保持一致:
// 匹配你生产代码中的PAGED_LIST_CONFIG参数 val testPagedConfig = PagedList.Config.Builder() .setPageSize(20) .setEnablePlaceholders(false) // 测试场景下建议关闭占位符,避免额外逻辑干扰 .setInitialLoadSizeHint(20) .build()
然后实现一个Fake DataSource,用于返回固定的测试数据(这里以PageKeyedDataSource为例,你可以根据实际使用的DataSource类型调整):
class FakeFooDataSource(private val testItems: List<Foo>) : PageKeyedDataSource<Int, Foo>() { // 返回初始加载的测试数据 override fun loadInitial( params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, Foo> ) { callback.onResult(testItems, null, 1) } // 测试场景下不需要加载更多,直接返回空列表 override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, Foo>) { callback.onResult(emptyList(), null) } // 同理,不需要向前加载 override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, Foo>) { callback.onResult(emptyList(), null) } }
最后用PagedList.Builder组装出测试实例:
// 构造测试用的Foo列表 val testFoos = listOf(Foo(id = 1, name = "Test Foo 1"), Foo(id = 2, name = "Test Foo 2")) val fakeDataSource = FakeFooDataSource(testFoos) // 生成最终的测试PagedList val TEST_PAGED_LIST_OF_FOOS = PagedList.Builder(fakeDataSource, testPagedConfig) .setNotifyExecutor(Executors.newSingleThreadExecutor()) .setFetchExecutor(Executors.newSingleThreadExecutor()) .build()
方法二:封装成工具函数复用
为了避免重复代码,你可以把上面的逻辑封装成一个工具函数:
fun createTestPagedList(foos: List<Foo>): PagedList<Foo> { val config = PagedList.Config.Builder() .setPageSize(20) .setEnablePlaceholders(false) .build() val dataSource = object : PageKeyedDataSource<Int, Foo>() { override fun loadInitial( params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, Foo> ) = callback.onResult(foos, null, 1) override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, Foo>) = callback.onResult(emptyList(), null) override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, Foo>) = callback.onResult(emptyList(), null) } return PagedList.Builder(dataSource, config) .setNotifyExecutor(Executors.newSingleThreadExecutor()) .setFetchExecutor(Executors.newSingleThreadExecutor()) .build() }
之后在测试代码里就能直接调用:
val testFoos = listOf(Foo(1), Foo(2)) val TEST_PAGED_LIST_OF_FOOS = createTestPagedList(testFoos) `when`(repository.getFoos()).thenReturn(Observable.just(TEST_PAGED_LIST_OF_FOOS))
额外测试注意事项
- 调度器处理:由于RxJava默认使用异步调度器,测试时可能会导致时序问题,建议在测试初始化时替换为同步调度器:
@Before fun setupRxSchedulers() { RxJavaPlugins.setIoSchedulerHandler { Schedulers.trampoline() } RxJavaPlugins.setComputationSchedulerHandler { Schedulers.trampoline() } RxJavaPlugins.setNewThreadSchedulerHandler { Schedulers.trampoline() } } - 模拟加载状态:如果需要测试加载更多、空状态或错误场景,可以修改Fake DataSource的
loadAfter方法,比如返回更多数据、抛出异常,来覆盖不同的业务场景。
内容的提问来源于stack exchange,提问作者isuPatches
相关产品推荐
相关产品推荐

