如何在kotlinx.coroutines.runTest中用JUnit assertThrows断言挂起函数异常?
解决协程测试中断言挂起函数抛出异常的IDE错误
问题原因
JUnit标准的Assertions.assertThrows接收的是普通非挂起Lambda,而挂起函数必须在协程体或另一个挂起函数内调用,因此直接在该Lambda中调用mySuspendFun()会触发IDE错误「Suspension functions can be called only within coroutine body」。
解决方案
使用kotlinx-coroutines-test库提供的挂起版assertThrows扩展函数,它专门支持在Lambda中调用挂起函数,完美适配runTest的协程测试上下文。
修改后的代码示例
@OptIn(ExperimentalCoroutinesApi::class) @Test fun `check that error is thrown`() = runTest { val thrownEx: BadRequestException = assertThrows<BadRequestException> { myService.mySuspendFun() } // 可对异常做后续断言,比如验证错误信息 assertEquals("预期的请求错误提示", thrownEx.message) }
注意事项
确保已导入kotlinx-coroutines-test的扩展函数:
import kotlinx.coroutines.test.assertThrows
备选方案(不推荐)
若坚持使用JUnit原生assertThrows,可在Lambda内部用runBlocking包裹挂起函数调用,但这种方式会额外创建独立协程上下文,可能干扰runTest的测试环境:
@OptIn(ExperimentalCoroutinesApi::class) @Test fun `check that error is thrown`() = runTest { val thrownEx: BadRequestException = Assertions.assertThrows(BadRequestException::class.java) { runBlocking { myService.mySuspendFun() } } }
内容的提问来源于stack exchange,提问作者Irina S.
相关产品推荐
相关产品推荐

