4

I'd like to write an integration test on my whole application, and want to mock only one specific method: the RestTemplate that I use to send some data to an external webservice and receive the response.

I want to read the response instead from a local file (to mock and mimic the external server response, so it is always the same).

My local file should just contain thejson/xml response that in production the external webserver would respond with.

Question: how can I mock an external xml response?

@Service
public class MyBusinessClient {
      @Autowired
      private RestTemplate template;

      public ResponseEntity<ProductsResponse> send(Req req) {
               //sends request to external webservice api
               return template.postForEntity(host, req, ProductsResponse.class);
      }
}

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class Test {

   @Test
   public void test() {
        String xml = loadFromFile("productsResponse.xml");
        //TODO how can I tell RestTemplate to assume that the external webserver responded with the value in xml variable?
   }
}
membersound
  • 81,582
  • 193
  • 585
  • 1,120
  • Use `MockRestServiceServer`, see https://stackoverflow.com/questions/42409768/how-to-mock-resttemplet-with-mockrestserviceserver and https://docs.spring.io/spring/docs/5.0.2.RELEASE/spring-framework-reference/testing.html#spring-mvc-test-client – M. Deinum Dec 08 '17 at 14:12

2 Answers2

5

Spring is so great:

    @Autowired
    private RestTemplate restTemplate;

    private MockRestServiceServer mockServer;

    @Before
    public void createServer() throws Exception {
        mockServer = MockRestServiceServer.createServer(restTemplate);
    }

    @Test
    public void test() {
        String xml = loadFromFile("productsResponse.xml");
        mockServer.expect(MockRestRequestMatchers.anything()).andRespond(MockRestResponseCreators.withSuccess(xml, MediaType.APPLICATION_XML));
    }
membersound
  • 81,582
  • 193
  • 585
  • 1,120
  • See: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html – slim Dec 08 '17 at 15:07
0

You can implement mocking framework like Mockito for this:

So, in your resttemplate mock you would have:

when(restTemplate.postForEntity(...))
    .thenAnswer(answer(401));

and answer implementation something like:

private Answer answer(int httpStatus) {
    return (invocation) -> {
        if (httpStatus >= 400) {
            throw new RestClientException(...);
        }
        return <whatever>;
    };
}

For further reading follow Mockito

Yogi
  • 1,805
  • 13
  • 24
  • 1
    OP wants to mock the raw web-service XML response, not the parsed and instantiated object returned by `RestTemplate`. – Snackoverflow Aug 17 '20 at 04:31