0

I'm testing a Java REST client using Wiremock, specifically how it handles an empty response.

Code under test:

public Content makeRequest(...) { 
    try {
        ResponseEntity response = restTemplate.exchange(...);
        if(response.getStatusCode() != 200) {
           throw new BadStatusCodeException(response.getStatusCode());
        }
        return extractContent(response);
    } catch (IOException e) {
        throw new ProtocolException(e);
    }    
}

Test:

Wiremock.stubFor(put(urlPathEqualTo("/foo"))
            .willReturn(aResponse().withFault(EMPTY_RESPONSE)));

thrown.expect(ProtocolException.class);

client.makeRequest();

This test passes on my local machine, but on our build machine it fails, throwing a BadStatusException with status code 500.

My best guess is that on my local machine, RestTemplate is making a direct connection to the Wiremock server, but that on the build machine the connection is going via a proxy -- perhaps because of an environment variable etc. -- and that the proxy is returning a 500 error when it encounters the fault simulated by WireMock.

Forcing my RestTemplate to use Apache HttpClient, like this:

ClientHttpRequestFactory httpRequestFactory = 
    new HttpComponentsAsyncClientHttpRequestFactory();
RestTemplate restTemplate = new RestTemplate(httpRequestFactory);

... seems to fix the problem, but I don't really want to bring extra dependencies into this library (the consumer of this library will inject their own RestTemplate, configured however they like).

Is my theory plausible? How can I verify this is what's happening? How can I force RestTemplate to connect directly? What other explanations could there be?

slim
  • 40,215
  • 13
  • 94
  • 127
  • Are you sur that wiremock runs well on the build machine? maybe it has not been started because the port is being used. – andolsi zied Nov 23 '16 at 16:50
  • Srping resttemplate makes direct connection to the URL except when you tell it to use a proxy. I guess there is some other issue in your case – Angelo Immediata Nov 23 '16 at 17:59
  • @andolsizied I'm sure Wiremock is working because other tests check `200 OK` scenarios and pass. – slim Nov 23 '16 at 22:46
  • which wiremock version you used? could enable logs and see what wiremock is receiving and what is it waiting for. – andolsi zied Nov 24 '16 at 09:27
  • @AngeloImmediata by default RestTemplate uses HttpUrlConnection, which honours the `http.proxyHost` system property -- although I have tried unsetting this. – slim Nov 24 '16 at 09:53
  • @slim as far as i know in spring 4 resttemplate uses httpclient... at least in my case it uses httpclient – Angelo Immediata Nov 24 '16 at 09:57
  • @AngeloImmediata read the Javadoc (or the source). It uses a `SimpleClientHttpRequestFactory` by default, which is a wrapper around `HttpUrlConnection`. It's *better* to use the `HttpComponentsClientHttpRequestFactory`, I agree. – slim Nov 24 '16 at 10:10
  • @andolsizied Wiremock 2.3.1 -- the logs are a bit bulky around where it happens because I think Wiremock prematurely closes the channel to simulate the fault, whereupon Jetty throws IOExceptions. But both local and build machine builds look about the same (exact order varies because of threading) – slim Nov 24 '16 at 10:41
  • @andolsizied using the Apache client seems to fix it, which as far as I can see rules out Wiremock being the source of the problem. – slim Nov 24 '16 at 11:00

0 Answers0