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

如何让Mock的挂起函数抛出受检异常?Mockito实践疑问

调用Suspend函数时Mockito抛出检查异常的问题解决

问题场景

在mock挂起函数时,使用thenThrow(Class<T>)抛出检查异常会触发Mockito的校验错误:

private fun mockServiceResponse() = service.stub {
    onBlocking { loadMessages(Mockito.any() ?: createInstance()) }
        .thenThrow(SocketException::class.java)
}

报错信息:

Checked exception is invalid for this method!
Invalid: java.net.SocketException
org.mockito.exceptions.base.MockitoException:

但换成thenAnswer手动抛出异常就可以正常工作:

private fun mockServiceResponse() = service.stub {
    onBlocking { loadMessages(Mockito.any() ?: createInstance()) }
        .thenAnswer { throw SocketException() }
}

原因分析

Mockito的thenThrow(Class<T>)会严格校验异常是否符合被mock方法的异常声明:挂起函数编译后会自动添加Continuation参数,但原方法并没有声明抛出SocketException这类检查异常,所以Mockito判定该异常非法并报错。

而thenAnswer是直接在mock的执行逻辑中手动抛出异常,绕过了Mockito的静态异常校验。协程环境中,检查异常会被自动处理或包装,手动抛出时不会触发Mockito的声明校验。

解决方案

  • 方案一:使用thenAnswer手动抛出异常(已验证可行)
    就是你已经用到的方式,直接在thenAnswer的lambda里抛出目标异常即可。

  • 方案二:包装检查异常为运行时异常
    如果偏好使用thenThrow,可以把检查异常包装成运行时异常抛出,避免Mockito的校验:

    private fun mockServiceResponse() = service.stub {
        onBlocking { loadMessages(Mockito.any() ?: createInstance()) }
            .thenThrow(RuntimeException(SocketException()))
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 11:16:03