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

Android ViewModel StateFlow单元测试协程超时问题求助

Android ViewModel协程单元测试超时问题求助

我正在开发一个Android项目,使用Retrofit进行网络请求从服务器获取数据,采用StateFlow存储并向UI层传递数据,功能层面运行完全正常。

为ViewModel编写成功、失败场景的单元测试时,出现协程超时错误,疑似存在协程泄漏,希望能得到帮助。我已查阅相关StackOverflow回答但没有解决问题,也愿意重写覆盖加载、成功与失败场景的ViewModel测试用例。


错误信息

After waiting for 60000 ms, the test coroutine is not completing
kotlinx.coroutines.test.UncompletedCoroutinesError: After waiting for 60000 ms, the test coroutine is not completing
    at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTestCoroutine$3$3.invokeSuspend(TestBuilders.kt:342)
    (Coroutine boundary)
    at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt.runTestCoroutine(TestBuilders.kt:326)
    at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTest$1$1.invokeSuspend(TestBuilders.kt:167)
    at kotlinx.coroutines.test.TestBuildersJvmKt$createTestResult$1.invokeSuspend(TestBuildersJvm.kt:13)
Caused by: kotlinx.coroutines.test.UncompletedCoroutinesError: After waiting for 60000 ms, the test coroutine is not completing
    at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTestCoroutine$3$3.invokeSuspend(TestBuilders.kt:342)
    at app//kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)

ViewModel代码

private val _uiCaseListState = MutableStateFlow<Resource<List<Case>>?>(null)
val uiCaseListState: StateFlow<Resource<List<Case>>?> get() = _uiCaseListState

fun fetchCaseList() {
    viewModelScope.launch(Dispatchers.IO) {
        inboxRepository.fetchCaseList().collect { response ->
            when {
                response.isSuccessful -> {
                    response.body()?.let { caseList ->
                        val filterCaseList = caseList.sortedByDescending { case ->
                            case.createdDate.time
                        }
                        _uiCaseListState.emit(Resource.Success(filterCaseList))
                    }
                }
                !response.isSuccessful -> {
                    _uiCaseListState.emit(Resource.Failure(ErrorCode.GENERAL_ERROR))
                }
                else -> {
                    _uiCaseListState.emit(Resource.Failure(ErrorCode.GENERAL_ERROR))
                }
            }
        }
    }
}

单元测试代码

@Test
fun fetchCaseList_Success_CaseList() = runTest {
    // Arrange
    val repo = InboxRepository(object : InboxApi {
        override suspend fun fetchCaseList(): Response<List<Case>?> {
            return Response.success(testCaseList)
        }
    })
    val vm = InboxViewModel(repo)

    // Act
    vm.fetchCaseList()

    // Assert
    assertEquals(Resource.Success(testCaseList).data.size, vm.uiCaseListState.drop(1).first()!!.data!!.size)
}

/**
 * "kotlinx.coroutines.test.UncompletedCoroutinesError:After waiting for 60000 ms, the test coroutine is not completing"
 */
@Ignore
@Test
fun fetchCaseList_Failure_GENERAL_ERROR() = runTest {
    // Arrange
    val error: Response<List<Case>?> = Response.error(
        400,
        "{\"key\":[\"someError\"]}"
            .toResponseBody("application/json".toMediaTypeOrNull())
    )
    val repo = InboxRepository(object : InboxApi {
        override suspend fun fetchCaseList(): Response<List<Case>?> {
            return error
        }
    })
    val vm = InboxViewModel(repo)

    // Act
    vm.fetchCaseList()

    // Assert
    assertEquals(Resource.Failure<Error>(ErrorCode.GENERAL_ERROR), vm.uiCaseListState.drop(1).first())
}

内容的提问来源于stack exchange,提问作者Arpit Patel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 00:39:53