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

如何在Mockk单元测试中验证不同CoroutineScope的方法调用?

如何验证CoroutineScope中执行的依赖方法调用

我尝试验证依赖对象中的方法是否被调用,但由于该方法在不同的CoroutineScope中执行,coVerify始终验证失败。请问如何验证someMethod()已被调用?

SUT代码

class SomeClass(
    private val coroutineScope: CoroutineScope,
    private val someDependency: SomeDependency
) {
    fun run() {
        coroutineScope.launch {
            someDependency.someMethod()
        }
    }
}

依赖类代码

class SomeDependency {
    fun someMethod() {
        println("SomeDependency.someMethod")
    }
}

失败的测试代码

class SomeClassTest {
    @MockK(relaxed = true)
    private lateinit var someDependency: SomeDependency

    private val testScope = TestScope()
    private lateinit var someClass: SomeClass

    @Before
    fun setup() {
        MockKAnnotations.init(this)
        someClass = SomeClass(
            testScope,
            someDataSource // 这里存在笔误,应该是someDependency
        )
    }

    @Test
    fun `when run, should call someDependency someMethod`() = runTest {
        someClass.run()
        coVerify { someDependency.someMethod() }
    }
}

解决方案

1. 手动等待TestScope中的协程完成

runTest不会自动等待你自定义的testScope内的协程执行完毕,需要显式调用testScope.advanceUntilIdle()或testScope.runCurrent()来触发所有挂起任务执行:

@Test
fun `when run, should call someDependency someMethod`() = runTest {
    someClass.run()
    testScope.advanceUntilIdle() // 等待testScope中所有协程完成
    coVerify { someDependency.someMethod() }
}

2. 使用runTest内置的CoroutineScope

直接将runTest提供的CoroutineScope传给SUT,这样runTest会自动管理该Scope下的所有协程,无需手动等待:

class SomeClassTest {
    @MockK(relaxed = true)
    private lateinit var someDependency: SomeDependency

    private lateinit var someClass: SomeClass

    @Before
    fun setup() {
        MockKAnnotations.init(this)
    }

    @Test
    fun `when run, should call someDependency someMethod`() = runTest {
        someClass = SomeClass(this, someDependency)
        someClass.run()
        coVerify { someDependency.someMethod() }
    }
}

3. 修复测试代码中的笔误

原测试代码的setup方法中,初始化SomeClass时传入的是someDataSource,但实际变量名是someDependency,这会导致SUT使用的不是Mock对象,直接导致验证失败,必须修正:

@Before
fun setup() {
    MockKAnnotations.init(this)
    someClass = SomeClass(
        testScope,
        someDependency // 修正笔误
    )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 04:45:57