You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Room数据库单元测试运行报job未完成异常如何解决

错误核心原因
  • 你将Room返回的Flow通过asLiveData()转为LiveData后,未触发LiveData的观察逻辑,对应Flow的收集协程没有启动,且asLiveData()默认使用Dispatchers.IO调度器,和runBlockingTest使用的测试协程调度器不兼容,测试结束时该IO协程任务还未完成,因此抛出This job has not completed yet异常。
  • 即使调度问题解决,你直接取receivedItem.value也会得到null,因为未激活的LiveData不会主动从Flow里拉取数据,断言必然失败。
修复方案

方案1:直接测试Flow(推荐,最简便)

不需要转LiveData,直接获取Flow的第一个发射值即可完成断言,修改测试方法代码如下:

@ExperimentalCoroutinesApi
@Test
@Throws(Exception::class)
fun insertAndGetItem() = runBlockingTest {
    val boira = Item(0, "Boira", 0.35, 36)
    val apple = Item(0, "Apple", 0.60, 50)
    val mango = Item(0, "Mango", 2.10, 43)

    itemDao.insert(boira)
    itemDao.insert(apple)
    itemDao.insert(mango)

    // 直接获取Flow的第一个值,不需要转LiveData
    val receivedItem = itemDao.getAllItems().first()
    assertThat(receivedItem.size, equalTo(3))
}

需要额外导入Flow的first扩展:import kotlinx.coroutines.flow.first

方案2:保留LiveData测试逻辑

如果你确实需要测试转为LiveData后的逻辑,需要做以下修改:

  1. 添加测试依赖:在build.gradle(模块级)的androidTestImplementation中引入androidx.arch.core:core-testing:2.2.0(可替换为对应最新版本)
  2. 测试类中添加LiveData同步执行规则,保证LiveData的操作都在当前线程执行:
@get:Rule
val instantTaskExecutorRule = InstantTaskExecutorRule()
  1. 使用LiveData测试的getOrAwaitValue()扩展方法主动获取值,修改测试方法对应代码:
val receivedItem = itemDao.getAllItems().asLiveData().getOrAwaitValue()
assertThat(receivedItem.size, equalTo(3))

内容的提问来源于stack exchange,提问作者Raw Hasan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 09:27:05