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

