Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MockRestServiceServer handling multiple Async requests

I have an orchestrator spring boot service that makes several async rest requests to external services and I would like to mock the responses of those services.

My code is:

 mockServer.expect(requestTo("http://localhost/retrieveBook/book1"))
    .andExpect(method(HttpMethod.GET))
    .andRespond(MockRestResponseCreators.withStatus(HttpStatus.OK)
        .body("{\"book\":{\"title\":\"xxx\",\"year\":\"2000\"}}")
            .contentType(MediaType.APPLICATION_JSON));

mockServer.expect(requestTo("http://localhost/retrieveFilm/film1"))
    .andExpect(method(HttpMethod.GET))
    .andRespond(MockRestResponseCreators.withStatus(HttpStatus.OK)
        .body("{\"film\":{\"title\":\"yyy\",\"year\":\"1900\"}}")
            .contentType(MediaType.APPLICATION_JSON));

service.retrieveBookAndFilm(book1,film1);
        mockServer.verify();

The retrieveBookAndFilm service calls two methods asynchronous one to retrieve the book and the other to retrieve the film, the problem is that sometimes the films service is executed first and I get an error:

java.util.concurrent.ExecutionException: java.lang.AssertionError: Request URI expected:http://localhost/retrieveBook/book1 but was:http://localhost/retrieveFilm/film1

Any idea how can I solve this issue, is there something similar to mockito to say when this url is executed then return this or that?

Thanks Regards

like image 209
Endika Avatar asked Dec 13 '17 12:12

Endika


1 Answers

I ran into the same issue and found it was caused by two things

  1. The default MockRestServiceServer expects the requests in the order you define them. You can get around this by creating your MockRestServiceServer like so:

MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build()

  1. (Possibly) In order to use the same URI twice, use the mockServer.expect(ExpectedCount.manyTimes(), RequestMatcher) method to build your response.

mockServer.expect(ExpectedCount.manyTimes(), MockRestRequestMatchers.requestTo(myUrl)) .andExpect(MockRestRequestMatchers.method(HttpMethod.GET)) .andRespond(createResponse())

I found the solution through the combination these two other answers which might offer more information.

How to use MockRestServiceServer with multiple URLs?

Spring MockRestServiceServer handling multiple requests to the same URI (auto-discovery)

like image 145
Kirsten Crear Avatar answered Jan 04 '23 12:01

Kirsten Crear