Kotlin Flow emitAll未被收集问题:networkBoundResource单元测试异常排查
Kotlin版networkBoundResource单元测试emitAll不生效原因分析
核心原因有以下三类,按出现概率排序:
调度器未绑定测试作用域
你在测试中单独实例化了TestCoroutineDispatcher,但这个实例没有和TestCoroutineRule的协程作用域关联。networkBoundResource通过flowOn(coroutineDispatcher)将整个流的执行切换到了这个独立的调度器上,而runBlockingTest默认只会调度自身关联的调度器任务,独立调度器上的逻辑(包括emitAll需要执行的流收集、后续值发射逻辑)根本没有被执行,测试就已经结束,因此只能拿到第一个emit的loading值。query返回无限流导致toList永远无法返回
如果你的query()方法是Room等ORM框架生成的数据库观察流,这类流会持续监听数据库变更,永远不会发送结束信号。而toList()是挂起函数,必须等待流完全结束才会汇总所有发射值返回,因此即使emitAll正常工作,toList()也会一直挂起,你永远拿不到后续的发射结果。
针对该场景的测试建议:使用
take(n)操作符指定要取的发射个数后再调用toList(),比如你预期流会发射3个值,就写.take(3).toList()。
- 依赖Mock不符合预期导致逻辑中断
如果你的queryDatabase()、shouldFetch、fetch等依赖的Mock实现不符合预期,也会导致逻辑走不到emitAll步骤:- 若
queryDatabase()返回的流没有发射任何值,firstOrNull()会一直挂起等待第一个值,后续逻辑完全不会执行 - 若
fetch()方法被Mock为永久挂起或者抛出未捕获的异常,也会中断执行,无法走到emitAll逻辑
- 若
内容的提问来源于stack exchange,提问作者muetzenflo
相关产品推荐
相关产品推荐

