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
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)
application-demo.properties
to be used for demo purposeWireMock
serviceThis 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.