Open In App

Introduction to WireMock

Last Updated : 05 Aug, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

WireMock is a tool for mocking HTTP-based APIs that run in the unit tests, on the desktop, or in the test environment. We can also say it is a simulator for HTTP-based APIs, considered a service virtualization tool or a mock server. It enables you to stay productive when an API you depend on

  • Doesn't exist or
  • Isn't complete or
  • Costly to access

It supports the testing of Edge cases and failure modes. It's fast so reduces build time significantly. In simple terms, Wiremock is a mocking setup for integration testing. It is mainly used during the development and more significantly during the Integration testing while a system or service talks to one or multiple external or internal dependencies/services. Now let's understand the whole WireMock concept through a simple real-world example. 

Example

For example, we are building a Muzix application and we have a feature inside this app where we have to connect with an external API provided by Spotify, or Ganna. But the question is how to perform the integration testing with the external APIs. So there will be two approaches to performing this task.

1. First Approach

This approach is so obvious. That means we can test with some testing environment or the actual production environment. But in this approach we have to face the following challenges:

  • Many times there are costs involved in hitting an API.
  • The external API system might not be always available which means we are totally dependent on the external system and any downtime in that system, will affect our tests and indirectly the release process.
  • The external API system might or might not have a test environment which means a music search API might always require a real ISRC (International Standard Recording Code) ID to fetch and return responses. 
Production System - WireMock
 


2. Second Approach 

The second approach will be why don't you use a mock server (Wiremock) which mocks responses to the requests received for the dependency. 

Test System - WireMock

Features of WireMock

  • Stubbing: It is a technique that allows configuring the HTTP response that is returned by the WireMock server when it receives a specific HTTP request. You can stub HTTP requests with WireMock by using the static givenThat() method of the WireMock class.
  • Verification: The WireMock server registers all requests it receives in memory until it is reset. And that makes it possible to verify that a request matching a specific pattern was received, and also to fetch the requests’ details. 
  • Record-playback of interactions: WireMock can create stub mappings from requests it has received. Combined with its proxying feature this allows you to “record” stub mappings from interaction with existing APIs.
  • Injection of faults and delays: One of the main reasons it’s beneficial to use web service fakes when testing is to inject faulty behavior that might be difficult to get the real service to produce on-demand. 
  • Simulation of Stateful Behaviour: Most web services tend to have some state, which changes as you and others interact with them. So it’s pretty useful to be able to simulate this when you’ve swapped a real service for a test double.
  • Can be used as,
    • JVM library in unit testing 
    • Run as a standalone process either on the same host or remote server or on the cloud. 
  • All of WireMock's features are easily accessible via its REST (JSON) interface and its' Java API. 

Maven Dependency for WireMock

In order to use the WireMock library, you need to include the following dependency in the pom.xml file

For Java 8: 

<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8</artifactId>
<version>2.33.2</version>
<scope>test</scope>
</dependency>

For Java 8 standalone:

<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8-standalone</artifactId>
<version>2.33.2</version>
<scope>test</scope>
</dependency>

Note: The Java version must be 8 or greater in order to use this dependency. 

Gradle Dependency for WireMock

In order to use the WireMock library, you need to include the following dependency in the build.gradle file. 

For Java 8: 

testImplementation "com.github.tomakehurst:wiremock-jre8:2.33.2"

For Java 8 standalone:

testImplementation "com.github.tomakehurst:wiremock-jre8-standalone:2.33.2"

Note: The Java version must be 8 or greater in order to use this dependency. 

Programmatically Managed Server

Since WireMock is being used in a programmatically managed server environment, the server can be configured and controlled using code in your tests.

Server Setup:

To set up WireMock programmatically, you need to create an instance of the WireMockServer class

Java
import com.github.tomakehurst.wiremock.WireMockServer;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;

public class WireMockProgrammatic {
    public static void main(String[] args) {
        WireMockServer wireMockServer = new WireMockServer(options().port(8080));
        wireMockServer.start();

        // Your stubbing and testing logic here

        wireMockServer.stop();
    }
}


Basic Usage:

Once the server is set up, you can define stubs to simulate API responses:

Java
import com.github.tomakehurst.wiremock.WireMockServer;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;

public class WireMockBasicUsage {
    public static void main(String[] args) {
        WireMockServer wireMockServer = new WireMockServer(options().port(8080));
        wireMockServer.start();

        wireMockServer.stubFor(get(urlEqualTo("/api/test/songs/12345"))
            .willReturn(aResponse()
                .withStatus(200)
                .withHeader("Content-Type", "application/json")
                .withBody("{ \"title\": \"Mock Song\", \"artist\": \"Mock Artist\" }")));

        // Your testing logic here

        wireMockServer.stop();
    }
}


JUnit Managed Server

Using WireMock with JUnit allows for automatic setup and teardown of the server during your test lifecycle.

Server Setup:

Integrate WireMock with JUnit by using the @Rule annotation:

Java
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import org.junit.Rule;
import org.junit.Test;

import static com.github.tomakehurst.wiremock.client.WireMock.*;

public class WireMockJUnitTest {
    @Rule
    public WireMockRule wireMockRule = new WireMockRule(8080);

    @Test
    public void testAPI() {
        stubFor(get(urlEqualTo("/api/test/songs/12345"))
                .willReturn(aResponse()
                    .withStatus(200)
                    .withBody("{ \"title\": \"Mock Song\", \"artist\": \"Mock Artist\" }")));

        // Perform your test assertions here
    }
}


URL Matching:

WireMock supports various URL matching strategies, such as exact matching and regular expressions:

stubFor(get(urlPathMatching("/api/test/songs/.*"))
.willReturn(aResponse().withStatus(200)));


Request Header Matching:

Match requests based on specific headers:

stubFor(get(urlEqualTo("/api/test/songs/12345"))
.withHeader("Accept", equalTo("application/json"))
.willReturn(aResponse().withStatus(200)));


Request Body Matching:

Match requests based on the request body:

stubFor(post(urlEqualTo("/api/song"))
.withRequestBody(containing("songId=12345"))
.willReturn(aResponse().withStatus(200)));


Stub Priority:

Control the priority of stubs to manage multiple matching scenarios:

stubFor(get(urlEqualTo("/api/song/12345"))
.atPriority(1)
.willReturn(aResponse().withStatus(200)));

stubFor(get(urlEqualTo("/api/song/12345"))
.atPriority(2)
.willReturn(aResponse().withStatus(404)));

Conclusion

WireMock is a very useful tool for developers and testers as it allows to stub and test HTTP-based APIs without using real external services. Due to the flexibility and control it offers it is suitable for integration testing and development settings.

Alternative Tool: Consider using Hoverfly as an alternative to WireMock.


Next Article
Article Tags :
Practice Tags :

Similar Reads