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

