A common scenario in many software projects is integration with external services. We integrate with data or authorization providers. We integrate using REST calls or gRPC or many other technologies.

When you want to test the integration of your application with an external service with which you communicate using HTTP, Wiremock can come as a handy tool. It provides a mechanism for recording and playback interaction with other API. The feature I would like to present you in this post is something I have recently discovered — support of stateful behaviour. In a few words —it allows you to emulate different responses based on previous interactions with Wiremock.

Photo by Pavan Trikutam on Unsplash

Example scenario

Let’s consider the following scenario: we want to retrieve a bunch of invoices from external service, but before we can do that we need to authorize our application. After successful authorization, we are able to properly download invoices data.

In terms of interactions, we want to emulate that any unauthorized call to /invoices endpoint with GET method will return 403 HTTP status code. When we send GET request to /auth we authorize the application and unlock /invoices endpoint. From now on we can send a request to /invoices endpoint and get 200 HTTP status code as a response. The flow diagram below shows the test scenario:

We can handle the above with aforementioned stateful behaviour feature. In this case, Wiremock acts as a state machine. In the beginning, it is in the Started state. After sending a request to /auth endpoint Wiremock changes its state to Authorized and properly handles requests to /invoices endpoint.

How to do it?

Basics

Photo by Markus Spiske on Unsplash

How can we tell Wiremock to act as in the example scenario? There are two ways to do it: by fluent Wiremock API or by JSON definition. Here, we will use the JSON definition. If you want to check fluent API you can visit http://wiremock.org/docs/stubbing/ ).

Wiremock requires that JSON should have at least request and response fields. The response field defines response (duh…) which will be sent to the client after receiving a matching request. So, for instance, the following JSON will return 200 HTTP status code in response to any GET request to /example endpoint:

Unauthorized responses

Photo by Paweł Czerwiński on Unsplash

Now we can proceed to our test scenario. First of all, we have to define a scenario in which the test will be executed. To quote the documentation: WireMock supports state via the notion of scenarios. A scenario is essentially a state machine whose states can be arbitrarily assigned. In the JSON definition, we introduce a new field scenarioName and set "Test scenario" as its value. The field acts like an identifier for a given test case. Additionally, there is a requiredScenarioState key which lets Wiremock apply given stub depending on at which state Wiremock is. We assigned Started value here because Wiremock always starts scenarios in Scenario.STARTED state. The first part of the example test case (unauthorized responses) can be defined using the following JSON:

Authorize

The second step of the example test case (authorizing an application) requires changing Wiremock state to authorized when it receives a proper GET request to the /auth endpoint. We can achieve this by adding newScenarioState to the stub. In the following example, it changes the current Wiremock state to Authorized .

Authorized responses

Photo by Richard Balog on Unsplash

Finally, after authorization, Wiremock can respond with a success to GET /invoices request. Stub definition below is very similar to the definition in the first step, except for the status code change, requiredScenarioState value is different. The new value means that the Wiremock will apply the stub then and only then when it is in at Authorized state otherwise this stub definition is ignored.

Check

Photo by Ousa Chea on Unsplash

Everything is set up, so now it’s the time to check if everything works properly. First of all, we have to set up a Wiremock server. I suggest using dockerized version of the server from https://github.com/rodolpheche/wiremock-docker . You can easily set up the server with just two commands:

Next, we have to send mappings to the Wiremock. All necessary mapping files ( unauthorized_invoices.json, authorize.json, authorized_invoices.json ) are saved in the same directory in which curl command is executed.

Everything is ready to go, so we can run requests for our test case:

Summary

Wiremock is a very powerful piece of software which lets you verify integrations with external HTTP services. It can save you a lot of time when implementing integration tests with external API calls. As you saw above, even complicated, stateful test scenarios can be easily done using the Stateful Behaviour feature.

Do you have any experience using Stateful Behaviour? Do you know any other cool feature of Wiremock? Let me know in the comments section below.