4

I know, we can mock our code in test scope easily in Spring-Boot. In here, I want to try create a demo-production scope/profile in Spring Boot. And in this profile, I want to work with mock sceneries.

For example, In my code, there are third party API calls:

String API_URL = "https://external.com/v1/%s";
private CloseableHttpClient httpClient;
public Result executeRequest(String apiVersion, String subUrl, HttpMethod httpMethod)
{
    try
    {
        HttpRequestBase httpRequest;
        String url = String.format(API_URL, subUrl);
        if (httpMethod.equals(HttpMethod.GET))
        {
            httpRequest = new HttpGet(url);
        }
        else if (httpMethod.equals(HttpMethod.POST))
        {
            httpRequest = new HttpPost(url);
            ((HttpPost) httpRequest).setEntity(new StringEntity(requestBody, "UTF-8"));
        }
        ...
        headers.forEach(httpRequest::setHeader);
        HttpResponse response = httpClient.execute(httpRequest);
    }
    catch (IOException e)
    {
        logger.error("IO Error: {}", e.getMessage());
        return handleExceptions(e);
    }
} 

Is there a way to mock it in production? Or better way; is there a way to create embedded server for it like (wiremock)?

Note: I have already implemented different profile properties on my project like (production, test and dev) so this is not related with to use different profiles. In here, I just want to mock API in production not in test profile. And of course for demo profile, I will create demo.properties

Sha
  • 921
  • 17
  • 46

1 Answers1

3

Solution 1:

It is possible to achieve the behavior with below configuration

@Configuration
@Profile("!demo")
public class ProductionConfiguration {

    // Real configuration
}


@Configuration
@Profile("demo")
public class ProductionConfiguration {

    // Mock configuration
}

As @MockBean annotation is part of spring test dependency, it won't be available when your application is deployed. You need to create mocks on your own Type mockObj = Mockito.mock(Type.class)

But this requires mockito dependency to be packaged as part of generated artifact.

Solution 2: (Recommended)

  • Externalize the API URL to properties file.
  • Create a separate properties file application-demo.properties to be used for demo purpose
  • Update URLs in this properties file to connect to an external WireMock service

This ensures that your production artifact doesn't need to contain unnecessary dependencies used only for demo purpose.

If required, you may choose to spin-up an embedded WireMock server when demo profile is active. But that means related dependencies must either be part of your dependencies or be available in classpath. If possible it is better to run WireMock as an external service.

Sample code for Solution 2 is available here for your reference.

Sudhir
  • 1,339
  • 2
  • 15
  • 36
  • Sudhir Thanks for your answer but I have already different profile properties on my project like (production, test and dev) so this is not related with to use different profiles. In here, I just want to mock API in production not test profile. So if you claim that Wiremock works here, could you please give me an example for my case? – Sha Jun 06 '20 at 10:53
  • @Sha I've done a sample application to demonstrate this. You can access it [here](https://github.com/sudhirtumati/embedded-wiremock-demo) – Sudhir Jun 06 '20 at 13:09
  • Sudhir Thanks for your answer. Please update your answer according to your comment/code. Then I will approve it. – Sha Jun 06 '20 at 14:42
  • @Sha the code sample I provided is based on Solution 2 in my answer (but with embedded `WireMock` server). May I know why you think it is different from my answer? – Sudhir Jun 06 '20 at 15:10
  • Please just link it on your answer as; sample code: GitHub link... – Sha Jun 06 '20 at 15:15