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

如何在Micronaut中使用Spock模拟ReadTimeoutException

解决Spock中模拟Micronaut ReadTimeoutException的问题

问题根源

你用Thread.sleep()的方式无法触发超时异常,因为Stub中的代码是在测试线程中执行的,sleep只是让当前线程暂停,并不会触发HttpClient内部的超时控制逻辑。正确的做法是直接在Stub的方法中抛出目标异常。

另外,若无法直接访问ReadTimeoutException,大概率是依赖版本问题或导入错误,该异常在Micronaut中是public类,先确认导入路径为io.micronaut.http.client.exceptions.ReadTimeoutException,并确保项目已引入正确的micronaut-http-client依赖。

解决方案

方案1:直接抛出异常(推荐)

修改Stub代码,在exchange方法的响应闭包中直接抛出ReadTimeoutException:

BlockingHttpClient blockingHttpClientStub = Stub(BlockingHttpClient.class)
blockingHttpClientStub.exchange(
        _ as MutableHttpRequest, TokenResponseBody.class
) >> {
    throw new ReadTimeoutException("模拟读取超时")
}
httpClient.toBlocking() >> blockingHttpClientStub

方案2:反射创建异常(当无法直接访问时)

如果确实因为权限问题无法直接实例化异常,可通过反射创建实例并抛出:

BlockingHttpClient blockingHttpClientStub = Stub(BlockingHttpClient.class)
blockingHttpClientStub.exchange(
        _ as MutableHttpRequest, TokenResponseBody.class
) >> {
    // 反射加载异常类并创建实例
    Class<?> exceptionClass = Class.forName("io.micronaut.http.client.exceptions.ReadTimeoutException")
    Constructor<?> constructor = exceptionClass.getConstructor(String.class)
    throw constructor.newInstance("模拟读取超时")
}
httpClient.toBlocking() >> blockingHttpClientStub

验证逻辑

运行测试时,Stub的exchange方法会直接抛出ReadTimeoutException,被业务代码中的catch (ReadTimeoutException re)块捕获,进而抛出CardTokenException,以此验证超时场景的处理逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 08:40:33