如何使用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
相关产品推荐
相关产品推荐

