I wrote an introduction before HttpClient Two kinds of retrial mechanism of , But we don't know if we will try again as expected .
It's provided to us by others API It's usually normal , Many errors don't recur stably , It also makes it impossible for us to conduct a comprehensive test . It is in this case that , I learned that WireMock.
This article does not intend to do an introductory tutorial , The point is how to use WireMock Solve practical problems .
Initialize the caller
First, initialize a HttpClient
public ZwroksApi(){
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(1000).build();
DefaultServiceUnavailableRetryStrategy serviceUnavailableRetryStrategy = new DefaultServiceUnavailableRetryStrategy();
httpClient = HttpClients.custom()
.setServiceUnavailableRetryStrategy(serviceUnavailableRetryStrategy)
.setDefaultRequestConfig(requestConfig)
.build();
}
The configuration is as follows
- Exception retries are enabled by default , retry 3 Time .
- Using the default service unavailable retry policy , Will try again 1 Time , interval 1 second .
- Set up SocketTimeout by 1 second , Used to simulate timeout .
Exception retry
Overtime
First, let's simulate the timeout , Set fixed delay 2 second , So it's going to be overtime , Try again as expected 3 Time , So it's a request 4 Time .
@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")));
}
But the result
Expected exactly 4 requests matching the following pattern but received 1
The specific reason has been mentioned in the previous article ,SocketTimeoutException
yes InterruptedIOException
Subclasses of , Won't try again .
How to time out and try again , It was also mentioned in the last article , I won't repeat it here .
Erroneous return
WireMock Several error returns are provided in , It's also easy to use
@Test
public void testBadResponse() {
stubFor(get(urlEqualTo("/test"))
.willReturn(aResponse().withFault(Fault.CONNECTION_RESET_BY_PEER)));
zwroksApi.test();
verify(4, getRequestedFor(urlEqualTo("/test")));
}
It's a mistake at runtime java.net.SocketException: Connection reset
, This kind of exception will happen , So here the test can pass .
Service unavailable, try again
The code called is as follows , I hope to return to 503 Try again
@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")));
}
The test here can also pass .WireMock Provides the ability to get request logs , Except for the times , We can see if the two requests are one second apart .
List<ServeEvent> allServeEvents = getAllServeEvents();
long firstTime = allServeEvents.get(1).getRequest().getLoggedDate().getTime();
long lastTime = allServeEvents.get(0).getRequest().getLoggedDate().getTime();
assert lastTime - firstTime > 1000;
Here's just a small part of WireMock The function of , More functions can go to the official website to see the document , Very easy to understand .