Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test a RestClientException with MockRestServiceServer

While testing a RestClient-Implementation I want to simulate a RestClientException that may be thrown by some RestTemplate-methods in that implementation f.e. the delete-method:

@Override
public ResponseEntity<MyResponseModel> documentDelete(String id) {
    template.setErrorHandler(new MyResponseErrorHandler());
    ResponseEntity<MyResponseModel> response = null;
    try {
        String url = baseUrl + "/document/id/{id}";
        response = template.exchange(url, DELETE, null, MyResponseModel.class, id);
    } catch (RestClientException ex) {
        return handleException(ex);
    }
    return response;
}

How can I achieve this?

I define the mock-server in this way:

@Before
public void setUp() {
    mockServer = MockRestServiceServer.createServer(template);
    client = new MyRestClient(template, serverUrl + ":" + serverPort);
}
like image 510
JMarky Avatar asked Mar 03 '17 11:03

JMarky


People also ask

What is@ RestClientTest?

@RestClientTest ensures that Jackson and GSON support is auto-configured, and also adds pre-configured RestTemplateBuilder and MockRestServiceServer instances to the context.

What is REST client exception?

RestClientException(java.lang.String pMessage) A constructor which takes a message, response object and error code. RestClientException(java.lang.String pMessage, java.lang.Throwable pCause) A constructor which takes a source exception, response object and error code.


2 Answers

You can test throwing runtime exceptions from the MockRestServiceServer, although this class, as of Spring 5.0.0.RC4, is not designed for it (which means it may not work for more complex use cases):

RestTemplate yourApi;
MockRestServiceServer server = MockRestServiceServer.createServer(yourApi);

server.expect(requestTo("http://..."))
    .andRespond((response) -> { throw new ResourceAccessException(
        new ConnectException("Connection reset")); });

It seems to work in tests:

  • where there's only one RestTemplate call,
  • where the exception is thrown as a result of the last expectation.

I wasn't able to expect two consecutive exceptions; the MockRestSeriviceServer (more concrete, the SimpleRequestExpectationManager) throws IllegalStateException on replaying the second expectation.

like image 187
MaDa Avatar answered Sep 21 '22 10:09

MaDa


You can take advantage of the MockRestResponseCreators for mocking 4xx or 5xx responses from the mockRestServiceServer.

For example for testing a 5xx - Internal server error:

mockServer.expect(requestTo("your.url"))
                .andExpect(method(HttpMethod.GET/POST....))
                .andRespond(withServerError()...);

In your case the RestClientException is thrown for client-side HTTP errors, so the example above can be fine tuned for a 4xx exception by using: ...andRespond(withBadRequest()); or ...andRespond(withStatus(HttpStatus.NOT_FOUND));

For a more simpler usage of these methods you use static imports for org.springframework.test.web.client.MockRestServiceServer,org.springframework.test.web.client.response.MockRestResponseCreators

like image 36
Alex Ciocan Avatar answered Sep 18 '22 10:09

Alex Ciocan