WireMock Tutorial: Introduction

This blog post gives a quick introduction to WireMock. After we have finished this blog post, we can identify its key features, we know when we should use it, and we can get the required dependencies with Maven and Gradle.

Let's get started.

What Is WireMock?

WireMock is a tool that can mimic the behavior of an HTTP API and capture the HTTP requests send to that API. It allows us to:

  • Configure the response returned by the HTTP API when it receives a specific request.
  • Capture the incoming HTTP requests and write assertions for the captured HTTP requests.
  • Identify the stubbed and/or captured HTTP requests by using request matching.
  • Configure request matchers by comparing the request URL, request method, request headers, cookies, and request body with the expected values.
  • Use WireMock as a library or run it as a standalone process.

Next, we will find out when we should use WireMock.

When Should We Use WireMock?

There are three situations when we should use WireMock:

First, we have to implement a feature which uses an HTTP API that is not ready. This is a quite common situation if we are doing greenfield development and we have to integrate our application with other systems (either internal or external) which aren't written by us. Also, if we are using the microservices architecture, the odds are that we will run into similar situations.

Second, we have to write unit tests for classes which use HTTP APIs. If we are writing unit tests for a class called A which uses another class called B that uses an HTTP API, the first thing that might come to our mind is to replace the B with a mock object when we are writing unit tests for the A class.

This is a good choice if the API client (B class) is provided by someone else because we can assume that the author of the client has ensured that it is working correctly. However, if the API client is written by us, using a mock object isn't a good choice because it doesn't allow us to verify that our code can communicate with the HTTP API.

In fact, I think that the best option is to test both A and B classes as one unit. This way we can verify that the correct information is send to the HTTP API, and ensure that all "legal" HTTP responses can be processed by the A and B classes.

Third, we have to write integration, API, or end-to-end tests for features which use external HTTP APIs. When we write these kinds of tests, we don't want to invoke external HTTP APIs because if our tests invoke an external HTTP API:

  • Our tests depend from the external HTTP API. Naturally, this means that our tests will fail if the external HTTP API is down. Also, it's very common that the external HTTP API doesn't allow us to initialize it into a known state before our tests are run. That's why we cannot write tests which use the data returned by the external HTTP API because we cannot know what kind of data will be returned.
  • Our tests are slower than they could be. The thing is that waiting a response from an external HTTP API takes a lot longer than getting the same response from WireMock. To make matters worse, we cannot use a short timeout because otherwise our tests could fail only because the timeout was too short and it was exceeded.
  • We cannot run our tests if we don't have a network connection. This is problem because there are places where we don't necessarily have a good network connection (like a train). Also, some APIs block requests which don't come from a "known" IP address. This means that having a working network connection might not good enough. We have to also be connected to the correct network.

In other words, if we don't want to write slow and inconsistent tests which can be run only if we are connected to the correct network, we should use WireMock.

Tests which use WireMock cannot guarantee that our application is compatible with the used HTTP APIs. These tests can only ensure that:

  • Our application sends the expected requests to the used HTTP API.
  • Our application is working as expected when it receives an expected response from the HTTP API.

In other words, if our expectations aren't correct, these tests are dangerous because they create a false sense of security. That's why we must always test these features manually before we deploy our application to the production environment.

Let's move on and find out how we can get the required dependencies with Maven and Gradle.

Getting the Required Dependencies

We can get the required dependencies by declaring one of these two dependencies in our build script:

  • The wiremock dependency contains only WireMock.
  • The wiremock-standalone dependency is a fat jar which contains WireMock and all its dependencies.

We can choose the correct dependency by following these three rules:

  • The wiremock dependency should be our default choice.
  • If we want to run WireMock as a standalone process, we should use the wiremock-standalone dependency.
  • If we use Spring Boot with Jetty, we should use the wiremock-standalone dependency because it helps us to avoid a conflict with the Jetty version.

Next, we will find out how we can get these dependencies with Maven and Gradle.

Getting the Required Dependencies With Maven

If we want to use the wiremock dependency, we have to add the following snippet to our pom.xml file:

<dependency>
    <groupId>com.github.tomakehurst</groupId>
    <artifactId>wiremock</artifactId>
    <version>2.16.0</version>
    <scope>test</scope>
</dependency>

If we want to use the wiremock-standalone dependency, we have to add the following snippet to our pom.xml file:

<dependency>
    <groupId>com.github.tomakehurst</groupId>
    <artifactId>wiremock-standalone</artifactId>
    <version>2.16.0</version>
    <scope>test</scope>
</dependency>
These examples assume that we will use WireMock when we write tests for our application. If we want to use WireMock when we implement a feature that uses an unfinished HTTP API, we must omit the scope of the dependency.

Getting the Required Dependencies With Gradle

If we want to use the wiremock dependency, we have to add the following snippet to our build.gradle file:

dependencies {
    testCompile(
            'com.github.tomakehurst:wiremock:2.16.0'
    )
}

If we want to use the wiremock-standalone dependency, we have to add the following snippet to our build.gradle file:

dependencies {
    testCompile(
            'com.github.tomakehurst:wiremock-standalone:2.16.0'
    )
}
These examples assume that we will use WireMock when we write tests for our application. If we want to use WireMock when we implement a feature that uses an unfinished HTTP API, we must add the required dependency to the compile dependency configuration.

Additional Reading:

We can now identify the key features of WireMock, we understand when we should use WireMock, and we can get the required dependencies.

Let's summarize what we learned from this blog post.

Summary

This blog post has taught us five things:

  • WireMock can mimic the behavior of an HTTP API and capture the HTTP requests send to that API.
  • WireMock allows us to implement a feature which uses an HTTP API that is not ready.
  • WireMock allows us to write fast and consistent tests.
  • Tests which use WireMock cannot guarantee that our application is compatible with the used HTTP APIs.
  • We can get the required dependencies by declaring either the wiremock or wiremock-standalone dependency in our build script.
5 comments… add one
  • Magnus Apr 4, 2018 @ 13:35

    I recommend taking a look at spring-cloud-contract-wiremock which makes setting up wiremock in spring boot tests very easy

    • Petri Apr 4, 2018 @ 21:58

      Thank for the tip! I will definitely take a closer look at it when I will write about WireMock and Spring Boot.

  • Pavs Jan 28, 2019 @ 18:34

    Hi Petri Kainulainen,

    Thanks for the blog. I need your suggestion for proceeding with WireMock.
    I am new to WireMock and need to know below possibilities can be achieved by this tool,

    1. Mocking the mobile application data Flow independent of the dev code base
    -> I am using Appium for regression test automation, on java platform. Is their a way I can keep this stub implementation in my automation framework (Repository independent of dev code base) and use Wiremock for my application while running with out any changes to devcode base.

    If possible can you please redirect to appropriate link to follow.

    Thanks in advance.

  • Mikail Aug 30, 2019 @ 1:22

    Excellent summary.

Leave a Reply