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

如何使用MockK测试Kotlin协程suspend挂起函数并验证接口调用次数

问题解答

1. 验证方法仅调用一次的实现

MockK的验证方法默认规则就是目标方法恰好被调用1次,你也可以显式传入exactly = 1参数让代码逻辑更可读。
注意由于你要验证的是suspend修饰的协程方法,必须使用MockK针对协程提供的coVerify方法,不能用普通的verify方法。

2. 测试代码必须放在runBlocking中执行

所有suspend方法只能在协程作用域或另一个suspend方法中调用,你的DataRepository.getCharacters()是挂起方法,单元测试的普通测试函数不支持直接调用挂起方法,因此必须用runBlocking(或协程测试库的runTest)包裹相关代码。


修正后的完整测试代码

你需要补全MockK的注解初始化逻辑,同时对suspend接口方法进行打桩,否则调用时会抛出异常:

import com.example.breakingbad.api.ApiServiceInterface
import com.example.breakingbad.data.DataRepository
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.impl.annotations.InjectMockKs
import io.mockk.impl.annotations.MockK
import io.mockk.MockKAnnotations
import org.junit.Before
import org.junit.Test
import kotlinx.coroutines.runBlocking

class DataRepositoryTest {
    @MockK
    private lateinit var apiServiceInterface: ApiServiceInterface

    @InjectMockKs
    private lateinit var dataRepository: DataRepository

    @Before
    fun setup() {
        // 初始化MockK注解
        MockKAnnotations.init(this)
        // 对suspend接口方法打桩,指定返回值
        coEvery { apiServiceInterface.getDataFromApi() } returns arrayListOf()
    }

    @Test
    fun getCharacters() = runBlocking {
        val response = dataRepository.getCharacters()
        // 验证方法恰好调用1次,exactly=1可以省略,默认就是该规则
        coVerify(exactly = 1) { apiServiceInterface.getDataFromApi() }
    }
}

如果你使用Junit5,也可以直接添加@ExtendWith(MockKExtension::class)注解到测试类上,省略手动调用MockKAnnotations.init初始化注解的步骤。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 01:06:02