0

Using spring boot I build an application which does HTTP request to an external distant service. For testing, I want to mock this external service instead of doing calls to the real service. When running full end-2-end test, the code still executes the HTTP requests, but I want it to call instead my mock server (in which I can check that the calls were made correctly).

Say the calls are made to api.example.com. Can I, using Java / Spring / JBehave programmatically and temporarily add a line to the hosts file or equivalent behavior in the JVM so that api.example.com resolves to localhost?

Philipp
  • 4,659
  • 9
  • 48
  • 69

2 Answers2

3

Solution 1: Spring profile

Assuming api.example.com is defined in your spring application.properties, the most common behavior is to override this property using the spring boot fallback mechanism associated to spring profile.

For example assuming api.example.com is associated to the property api.host key, You could create a spring profile integration-testing and its associated application properties files application-integration-testing.properties under src/test/resources. This file will contain api.host=localhost whereas the production application.properties contains api.host=api.example.com.

You annotate your test with @ActiveProfiles("integration-testing") and voila, api.host value will be localhost but only for testing.

Solution 2: Custom DNS resolver

It does not seems possible to have a custom resolver with the default implementation (HttpURLConnection). You can use a RestTemplate with an implementation of ClientHttpRequestFactory which allows a custom DNS resolver eg. the Apache HttpClient HttpComponentsClientHttpRequestFactory, see this answer for more detail.

Solution 3: Mock Rest template

You can use a RestTemplate mock using MockRestServiceServer. This solution does not involve a real http server.

Community
  • 1
  • 1
Nicolas Labrot
  • 4,017
  • 25
  • 40
  • Thanks. Yes this approach is what I had planned if I find no direct way of redirecting the calls with the real URL. I would rather have the calls done with the correct URL if possible. – Philipp Apr 11 '17 at 08:04
  • Which http client are you using? It may allow to define a custom DNS resolver. – Nicolas Labrot Apr 11 '17 at 08:12
  • I'm using RestTemplate – Philipp Apr 11 '17 at 08:14
  • It does not seems possible to have a custom resolver with the default implementation (`HttpURLConnection`). I see 2 possible solutions: 1) Use a RestTemplate mock using [`MockRestServiceServer`](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/test/web/client/MockRestServiceServer.html). This solution does not involve a real http server 2) Use a RestTemplate with a `ClientHttpRequestFactory` which allows a custom DNS resolver eg. the `Apache HttpClient` `HttpComponentsClientHttpRequestFactory`, [see this answer](http://stackoverflow.com/a/35327982/564005) – Nicolas Labrot Apr 11 '17 at 09:27
  • Thanks, I will try that. Could you add this to your answer, so I can accept it? – Philipp Apr 11 '17 at 16:41
  • I have added the 2 solutions to the answer. Thanks. – Nicolas Labrot Apr 11 '17 at 18:00
-1

I would say, you can use MockServer, and using RestAssured framework by which you can trace the call and redirect to mock server.

sandeshch
  • 11
  • 5