A Dropwizard application will often make a call out to another service - full integration testing therefore requires an instance of that service to be available. THis is not always possible, and for compile time testing (e.g. using JUnit) probably not desirable, as the unavailability of the external service will compromise the completion of tests. Wiremock provides the opportunity to provide mock endpoints which can replicate the external service and enable realistic integration testing without calling an external service.
Test Scenario
For the purpose of this document consider the following example where a service under tests makes a 'smokeTest' communication with a remote service, returning a result indicating whether the remote service is available or not. THe remote service can be considered unavailable if it cant be reached, or returns an invalid status. There are therefore 3 use cases
- Call an external service which is not running (e.g. HTTP 404)
- Call an external service which is running but returns an error (e.g. HTTP 500)
- Call an external service which is running successfully (e.g. HTTP 400)
External Service Stub
Wiremock is our friend here. It is relatively simple to create a class which will represent the external interface with Wirock. The following code illustrates how this might be achieve server = new WireMockServer(options().port(0));
server.start();
port = server.port();
configureFor("localhost", port);
stubFor(get(urlEqualTo("/ping"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("okay"))
);
In the above we do the following ;
Instantiate and start a WiremockServer on port zero. Using port zero means that Wiremock will find an unused port and allocate that - the allocated port can be retrieved.
We then set an expected behavior - in the above instance a call to "/ping" will return a Response with status 200 and a body of "okay" - i.e. the 'happy path'.
Modifying expected behaviour
The simple example above will always return a 'happy path' result - however we may wish to modify this. One simple way would be to amend the class as follows
// Define variable to hold the status
private int status;// Add Constructor Parameter to provide variable response
public MyWiremockServer(int status) {this.status = status;}// Use status in the response (i.e. modify the stubFor definition)
stubFor(get(urlEqualTo("/ping"))
.willReturn(aResponse()
.withStatus(status)..);
THe class is constructed with a status which is then used in the stubFor declaration.