Using Wiremock for Fun and Mocking

Reading Time: 3 minutes

Mocking – something we all need, and yet, usually, hate. Simply because writing mocks is a boring and cumbersome task. The good news – it doesn’t have to be like that. There are so many good alternatives that make mocking easier: From libraries that ease the process of writing the mock, though contract testing with Pact (which solve the problem in a totally different way) to automatically generating mocks using Swagger/Open API spec. All are really good solutions – but today I want to focus on WireMock: A tool that really makes mocking a fun.

Why WireMock?

WireMock is a mocking tool (like the name implied). It can be used programmatically to create a mock, but the interesting part is the interactive mode. In the interactive mode, you first use WireMock to record requests to the real API (by proxying the requests and responses). Once the recording completed, WireMock produces mocking from the proxied requests and responses. Using the interactive mode eliminate all the hard work of writing a mock and let you focus on your actual tests. Because the mocks are based on the recording of the actual traffic, the mock is identical to the original API, which makes the tests more reliable. And lastly – updating the mock is as simple as re-recording the requests/responses. Let’s take a look at a real example (or just take a look at Kamus end-to-end tests).

Mocking Kubernetes API

While working on Kamus (a secret encryption/decryption for Kubernetes), I had to mock Kubernetes API. Let’s see what how easy it is using WireMock!
After downloading and running WireMock (java -jar java -jar wiremock-standalone-2.18.0.jar), open http://localhost:8080/__admin/recorder/ in your browser:

WireMock recorder UI
Clean and simple UI

Fill the details of the target API (in my case, it is the local Kubernetes proxy URL – http://localhost:8001), and hit “Record”. Now, all we need to do is point our code to http://localhost:8080 instead of Kubernetes API, and run it. Now it’s time to play with our API – make sure to call every functionality so WireMock call record all the different requests and responses (and yes, this should include error cases). This is very similar to how you explorer an application with Zaproxy, just for different purposes…

After the code run completed, hit “Stop” in WireMock UI. Now if you’ll look at the folder when you run WireMock, you’ll notice a new folder there with the name “mapping”. This folder contains all the requests and responses recorded (see an example here).

Putting it all together

Now that we have the recording ready, all that is left is running the tests. To run the tests, I use docker-compose. This how the docker-compose.yaml look like in Kamus:

version: '3'
services:
  encryptor:
    image: $ENCRYPTOR_IMAGE
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
  decryptor:
    image: $DECRYPTOR_IMAGE
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - Kubernetes__ProxyUrl=http://wiremock:8080
   black-box:
    build:
      context: ../
    environment:
     - ENCRYPTOR=http://encryptor:9999/
     - DECRYPTOR=http://decryptor:9999/
     - TEAMCITY_PROJECT_NAME=api
     - PROXY_URL=http://zap:8090
     - KUBERNETES_URL=http://wiremock:8080
    volumes:
     - ./reports:/reports

  wiremock:
    build:
      context: ../Wiremock

I defined 4 services – Kamus API (encryptor and decryptor), tests, and WireMock. Notice the KUBERNETES_URL  environment variable – see how it points to Wiremock. Running WireMock in docker is really simple – this is the docker file:

FROM openjdk:8-stretch

WORKDIR /wiremock

RUN wget http://repo1.maven.org/maven2/com/github/tomakehurst/wiremock-standalone/2.17.0/wiremock-standalone-2.17.0.jar

COPY . .

CMD ["java", "-jar", "wiremock-standalone-2.17.0.jar"]

Notice the copy instruction – this where I copy the mapping folder.
Now that we have all set – all we need to do in order to run the tests is a simple docker compose command (take a look at Kamus CI if you don’t believe me):

docker-compose up --build --exit-code-from black-box.

The tests will run, and the code will use WireMock instead of Kubernetes API.

via GIPHY

Isn’t mocking with WireMock fun?

Leave a Reply

Your email address will not be published. Required fields are marked *