以前写了一篇介绍 HttpClient 的两种重试机制, 可是否真的会按照预期进行重试咱们不得而知。java
别人提供给咱们的 API 每每都是正常的,不少错误并不能稳定重现,这也形成了咱们没法进行全面的测试。正是这种状况下,了解到了 WireMock。segmentfault
本文不打算作一个入门教程,重点在于如何用 WireMock 解决实际的问题。测试
首先初始化一个HttpClient
ui
public ZwroksApi(){ RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(1000).build(); DefaultServiceUnavailableRetryStrategy serviceUnavailableRetryStrategy = new DefaultServiceUnavailableRetryStrategy(); httpClient = HttpClients.custom() .setServiceUnavailableRetryStrategy(serviceUnavailableRetryStrategy) .setDefaultRequestConfig(requestConfig) .build(); }
进行了以下配置url
首先来模拟一下超时,设置了固定的 delay 2秒,因此必定会超时,按照预期会重试3次,因此一共是请求4次。.net
@Test public void testSocketTimeOut() { stubFor(get(urlEqualTo("/test")) .willReturn(aResponse() .withStatus(HttpStatus.SC_OK) .withHeader("Content-Type", "text/xml") .withBody("ok") .withFixedDelay(2000))); zwroksApi.test(); verify(4, getRequestedFor(urlEqualTo("/test"))); }
可是结果呢日志
Expected exactly 4 requests matching the following pattern but received 1
具体的缘由在以前那篇文章也已经提过,SocketTimeoutException
是 InterruptedIOException
的子类,不会重试。code
如何超时也进行重试,在上一篇中也有讲,这里就不赘述了。xml
WireMock 中提供了几种错误返回,使用也很简单教程
@Test public void testBadResponse() { stubFor(get(urlEqualTo("/test")) .willReturn(aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER))); zwroksApi.test(); verify(4, getRequestedFor(urlEqualTo("/test"))); }
这里在运行时会抛错 java.net.SocketException: Connection reset
,这种异常是会进行重试的,因此这里测试能够经过。
调用的代码以下,我但愿在返回503的时候进行重试
@Test public void testServiceUnavailable() { stubFor(get(urlEqualTo("/test")) .willReturn(aResponse() .withStatus(HttpStatus.SC_SERVICE_UNAVAILABLE) .withHeader("Content-Type", "text/xml") .withBody("service unavailable"))); zwroksApi.test(); verify(2, getRequestedFor(urlEqualTo("/test"))); }
这里测试也是能够经过的。WireMock 提供了获取请求日志的能力,除了次数,咱们能够看看是否两次请求是间隔了一秒。
List<ServeEvent> allServeEvents = getAllServeEvents(); long firstTime = allServeEvents.get(1).getRequest().getLoggedDate().getTime(); long lastTime = allServeEvents.get(0).getRequest().getLoggedDate().getTime(); assert lastTime - firstTime > 1000;
这里只是介绍了一小部分 WireMock 的功能,更多的功能能够去官网看文档,很是好懂。