WireMock

Language: Java

Testing/Mocking

WireMock was created to provide a robust tool for testing HTTP-based integrations. It can be used for unit tests, integration tests, or contract tests, allowing developers to simulate API behavior, return custom responses, and verify HTTP requests. Its popularity grew as microservices and API-driven architectures became widespread.

WireMock is a flexible and powerful Java library for mocking HTTP services. It allows developers to stub, simulate, and test interactions with external APIs, enabling reliable and isolated testing of client code without depending on real external services.

Installation

maven: Add dependency in pom.xml: <dependency> <groupId>com.github.tomakehurst</groupId> <artifactId>wiremock-jre8</artifactId> <version>3.2.0</version> <scope>test</scope> </dependency>
gradle: Add dependency in build.gradle: testImplementation 'com.github.tomakehurst:wiremock-jre8:3.2.0'

Usage

WireMock allows developers to start a mock HTTP server, configure stubs, simulate delays or failures, and verify requests. It supports both programmatic and declarative (JSON) configuration and can run in unit tests or standalone mode.

Starting a WireMock server

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

WireMockServer wireMockServer = new WireMockServer(8080);
wireMockServer.start();

configureFor("localhost", 8080);
stubFor(get(urlEqualTo("/hello"))
        .willReturn(aResponse()
            .withHeader("Content-Type", "text/plain")
            .withBody("Hello WireMock!")));

// Shutdown
// wireMockServer.stop();

Starts a WireMock server, defines a stub for GET /hello, and returns a custom response.

Verifying requests

verify(getRequestedFor(urlEqualTo("/hello")));

Checks whether a specific HTTP request was made to the mock server.

Simulating delays and errors

stubFor(get(urlEqualTo("/slow"))
    .willReturn(aResponse()
        .withFixedDelay(2000) // 2 seconds delay
        .withStatus(500)
        .withBody("Server error")));

Simulates slow responses and server errors for testing client resilience.

Using JSON stubs

// Save a stub mapping as src/test/resources/__files/hello.json
{
  "request": { "method": "GET", "url": "/hello" },
  "response": { "status": 200, "body": "Hello from JSON!" }
}

Defines stubs declaratively using JSON files instead of programmatic API.

Recording and replaying requests

wireMockServer.startRecording("http://real-api-server.com");
// perform tests
wireMockServer.stopRecording();

Records real HTTP interactions to create stubs automatically for later replay.

Using WireMock with JUnit

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

@Rule
public WireMockRule wireMockRule = new WireMockRule(8080);

Integrates WireMock into JUnit tests for automatic setup and teardown of the mock server.

Error Handling

PortInUseException: Occurs if the configured port is already in use. Change the WireMock server port or stop the conflicting service.
VerificationFailedException: Occurs when a request verification fails. Ensure the request was made and matches the expected URL, method, and headers.
MappingNotFoundException: Occurs when no stub matches a request. Define appropriate stubs for all expected test requests.

Best Practices

Use WireMock for integration and contract testing to avoid dependency on real external services.

Keep stubs small and focused to simplify test maintenance.

Combine programmatic stubs with JSON-based stubs for flexibility.

Simulate realistic network conditions using delays and error responses.

Clean up or reset stubs between tests to ensure isolation.