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

Kotlin MockK如何验证后台协程作用域中的方法调用?

问题原因与解决方案

核心问题

测试失败的根本原因是ViewModel的backgroundScope未使用测试指定的testDispatcher,导致runCurrent()无法触发该协程执行,最终interactor.doBackground(null)从未被调用。

真机上backgroundScope依赖默认Dispatcher(如Dispatchers.IO)能正常执行,但测试中你没有将这个Dispatcher替换为测试可控的Dispatcher,协程会挂起在测试框架无法调度的线程上,自然不会被执行。

修复步骤

1. 让ViewModel支持Dispatcher注入(推荐)

修改ViewModel构造函数,将Dispatcher作为依赖传入,方便测试时替换:

class MyViewModel(
    private val interactor: MyInteractor,
    private val backgroundDispatcher: CoroutineDispatcher = Dispatchers.IO
) : ViewModel() {
    private val backgroundScope = CoroutineScope(backgroundDispatcher + genericErrorHandler)

    fun makeBackgroundCallAndClose() {
        backgroundScope.launch(genericErrorHandler) {
            interactor.doBackground(null)
        }
        navigate(NavigatorCommand.CloseScreen)
    }
}

2. 调整测试代码,绑定测试Dispatcher

  • 创建TestScope时关联testDispatcher
  • 给ViewModel传入测试Dispatcher
  • 用runCurrent()触发协程执行

修改后的测试代码:

@Test
fun `test my makeBackgroundCallAndClose`() = runTest(testDispatcher) {
    coEvery { interactor.doBackground(any()) } just runs

    val viewModel = MyViewModel(
        interactor,
        backgroundDispatcher = testDispatcher
    )

    viewModel.makeBackgroundCallAndClose()
    runCurrent() // 执行testDispatcher上所有待处理的协程任务

    coVerify(exactly = 1) {
        interactor.doBackground(null)
    }
}

3. 替代方案(不修改ViewModel构造)

如果不想改动ViewModel代码,可以通过测试框架强制替换默认Dispatcher:

@Test
fun `test my makeBackgroundCallAndClose`() = runTest(testDispatcher) {
    coEvery { interactor.doBackground(any()) } just runs

    // 强制将IO Dispatcher替换为测试Dispatcher
    Dispatchers.setIo(testDispatcher)
    val viewModel = MyViewModel(interactor, TestScope(testDispatcher))

    viewModel.makeBackgroundCallAndClose()
    runCurrent()

    coVerify(exactly = 1) {
        interactor.doBackground(null)
    }

    // 测试结束后恢复默认Dispatcher
    Dispatchers.resetIo()
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 19:38:30