Mocking API calls using WireMock
Published: 2021-05-28 08:52:27

---
title: Mocking API calls using WireMock
published: true
date: 2021-05-14 17:00:00 UTC
tags: 
canonical_url: https://www.alexhyett.com/mock-api-calls-wiremock/
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/znxw8yahu6dg020thdsh.jpg
---

It is rare in software development that you are building something in complete isolation from everything else. Generally, you are going to be making calls to other systems or components.

If you are lucky you are building against an existing API that you can test against. If you are working with other teams to similar deadlines, you generally need to agree on a contract beforehand and build against it. In this case, you are going to need to mock the API to be able to test what you are building.

This is where Wiremock comes in. Other tools that can be used for mocking APIs but Wiremock is the one I have the most experience with.

## Running Wiremock in a Docker container

If you need to run your component locally against a mocked source then running wiremock standalone from a docker container is the best way to do that. It works similarly to the way you mock AWS by running localstack. You can also use Wiremock to mock AWS services but I will save that for another post!

To save us some time we are going to use this popular (30 million pulls) docker image, [rodolpheche/wiremock-docker](https://github.com/rodolpheche/wiremock-docker).

If you want a one-liner to get this up and running you can use this:

```
docker run -it --rm -p 8080:8080 rodolpheche/wiremock
```

When wiremock starts you should see something like this on the console:

```
 /$$ /$$ /$$ /$$ /$$ /$$
| $$ /$ | $$|__/ | $$$ /$$$ | $$
| $$ /$$$| $$ /$$ /$$$$$$ /$$$$$$ | $$$$ /$$$$ /$$$$$$ /$$$$$$$| $$ /$$
| $$/$$ $$ $$| $$ /$$ __$$ /$$__ $$| $$ $$/$$ $$ /$$ __$$ /$$_____ /| $$ /$$/
| $$$$_ $$$$| $$| $$ \__/| $$$$$$$$| $$ $$$| $$| $$ \ $$| $$ | $$$$$$/
| $$$/ \ $$$| $$| $$ | $$ _____ /| $$\ $ | $$| $$ | $$| $$ | $$_ $$
| $$/ \ $$| $$| $$ | $$$$$$$| $$ \/ | $$| $$$$$$/| $$$$$$$| $$ \ $$
| __/ \__ /| __/|__ / \ _______/|__ / | __/ \______ / \ _______/|__ / \__/

port: 8080
enable-browser-proxying: false
disable-banner: false
no-request-journal: false
verbose: false

```

Got to love the ASCII art!

You should be able to get a list of mappings (which will be empty to start with) using `http://localhost:8080/__admin/mappings` which will give us this:

```
{
  "mappings": [],
  "meta": {
    "total": 0
  }
}
```

#### Adding mappings using the API

You can use the wiremock API to add mappings, this is particularly useful if you want to test out examples on the go.

##### GET Request

Using postman you can import the following `curl` statement:

```
curl --location --request POST 'http://localhost:8080/__admin/mappings/new' \
--header 'Content-Type: application/json' \
--data-raw '{
    "request": {
        "method": "GET",
        "url": "/api/test"
    },
    "response": {
        "status": 200,
        "body": "{ \"test\": \"data\" }",
        "headers": {
            "Content-Type": "application/json"
        }
    }
}'
```

Running this should give you a 201 created response.

Now when we call `http://localhost:8080/api/test` we should get back the following:

```
{
  "test": "data"
}
```

All you need to do is change the request and response and you can mock any API call.

##### POST Request

Mocking GET request by URL is the simplest option but if you are doing POST requests you are probably going to want to mock based on the request body.

For example, lets mock the POST endpoint that maps based on the body content:

```
curl --location --request POST 'http://localhost:8080/__admin/mappings/new' \
--header 'Content-Type: application/json' \
--data-raw '{
    "request": {
        "method": "POST",
        "url": "/api/test",
        "bodyPatterns" : [{
          "matchesJsonPath" : {
             "expression": "$",
             "equalToJson": "{ \"test\": \"banana\" }"
          }
        }]
    },
    "response": {
        "status": 201,
        "body": "{ \"test\": \"banana created\" }",
        "headers": {
            "Content-Type": "application/json"
        }
    }
}'
```

Just to prove it works we are now going to map another one based on a different body (fruit).

```
curl --location --request POST 'http://localhost:8080/__admin/mappings/new' \
--header 'Content-Type: application/json' \
--data-raw '{
    "request": {
        "method": "POST",
        "url": "/api/test",
        "bodyPatterns" : [{
          "matchesJsonPath" : {
             "expression": "$",
             "equalToJson": "{ \"test\": \"apple\" }"
          }
        }]
    },
    "response": {
        "status": 201,
        "body": "{ \"test\": \"apple created\" }",
        "headers": {
            "Content-Type": "application/json"
        }
    }
}'
```

You can test it out by running the following:

```
curl --location --request POST 'http://localhost:8080/api/test' \
--header 'Content-Type: application/json' \
--data-raw '{
    "test": "banana"
}'

curl --location --request POST 'http://localhost:8080/api/test' \
--header 'Content-Type: application/json' \
--data-raw '{
    "test": "apple"
}'
```

This is just a simple example, if you need something more advanced, check out the [request matching documentation](http://wiremock.org/docs/request-matching/) for more examples.

#### Resetting Mappings

If you want to reset all your mappings at any point then you can do so by sending a POST request to `http://localhost:8080/_admin/reset`

```
curl --location --request POST 'http://localhost:8080/__admin/reset'
```

#### Adding mappings using files

The other way to add your mock mappings is by using files that are loaded when the container is started. This is particularly useful if you want other developers to be able to run your code.

I prefer to run all my docker containers using `docker-compose`. That way all people need to do is run `docker-compose up` and everything will be set up for them.

Your `docker-compose.yml` file should look something like this:

```
version: '3.4'

services:
  wiremock:
    image: rodolpheche/wiremock
    container_name: wiremock
    volumes:
      - ./ __files:/home/wiremock/__ files
      - ./mappings:/home/wiremock/mappings
    ports:
      - 8080:8080
```

When you run `docker-compose up` it will create a `__files` and a `mappings` folder in your current directory that are mounted to the same folders in your container.

The `mappings` folder is where you save your json mappings. Each file is exactly the same as the body of the request that we were sending earlier.

For example:

```
{
  "request": {
    "url": "/api/test",
    "method": "GET"
  },
  "response": {
    "status": 200,
    "body": "{ \"test\": \"data\" }",
    "headers": {
      "Content-Type": "application/json"
    }
  }
}
```

If you want you can even just save the mappings we created by API earlier by sending a POST request to `http://localhost:8080/__admin/mappings/save`.

```
curl --location --request POST 'http://localhost:8080/__admin/mappings/save'
```

If you update any of the files that are saved in the `mappings` folder then you will need to run a reset before they take effect.

```
curl --location --request POST 'http://localhost:8080/__admin/reset'
```

The `__files` folder can be used to serve static files. For example if we put a simple `index.html` file in this folder like this:

```
<!DOCTYPE html>
<html>
  <body>
    <h1>Mocked File</h1>
    <p>Something interesting here</p>
  </body>
</html>
```

Then go to `http://localhost:8080` you should see this:

[![Mocked Website](https://www.alexhyett.com/static/f9a07b52591c1bfa2c7e453e7d76b075/c0255/mocked-website.png "Mocked Website")](/static/f9a07b52591c1bfa2c7e453e7d76b075/e8e04/mocked-website.png)

## Final Thoughts

Using mocks can be a great way to simulate the behaviour of external APIs. Wiremock is one of the simplest ways to get started. That being said, I have found that wiremock isn’t the fastest way to mock an API. I recently had to mock an FX rate endpoint with a set of static FX rates. It was much faster to do this with a simple API written in Node.js.

There is another version of Wiremock that I use regularly called [Wiremock.Net](https://github.com/WireMock-Net/WireMock.Net) which is particularly useful when writing .NET integration tests. I will cover that in my next post as it is a bit more involved than this one.