Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
A tool for mocking HTTP services
Java HTML XSLT Other

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
sample-war
src
.gitignore
LICENSE.txt
README.md
build.gradle
new-build.gradle

README.md

WireMock - a tool for simulating HTTP services

Key Features

  • HTTP response stubbing, matchable on URL, header and body content patterns
  • Request verification
  • Runs in unit tests, as a standalone process or as a WAR app
  • Configurable via a fluent Java API, JSON files and JSON over HTTP
  • Record/playback of stubs
  • Fault injection
  • Per-request conditional proxying
  • Stateful behaviour simulation
  • Configurable response delays

Using with JUnit 4.x

First, add WireMock as a dependency to your project. If you're using Maven, you can do this by adding this to your POM:

<repositories>
    <repository>
        <id>tomakehurst-mvn-repo-releases</id>
        <name>Tom Akehurst's Maven Release Repo</name>
        <url>http://tomakehurst.github.com/tomakehurst-mvn-repo/releases</url>
        <layout>default</layout>
    </repository>
</repositories>

...and this to your dependencies:

<dependency>
    <groupId>com.github.tomakehurst</groupId>
    <artifactId>wiremock</artifactId>
    <version>1.18</version>
</dependency>

In your test class, add this:

@Rule
public WireMockRule wireMockRule = new WireMockRule(8089); // No-args constructor defaults to port 8080

You can then write a test case like this:

@Test
public void exampleTest() {
    stubFor(get(urlEqualTo("/my/resource"))
            .withHeader("Accept", equalTo("text/xml"))
            .willReturn(aResponse()
                .withStatus(200)
                .withHeader("Content-Type", "text/xml")
                .withBody("<response>Some content</response>")));

    Result result = myHttpServiceCallingObject.doSomething();

    assertTrue(result.wasSuccessFul());

    verify(postRequestedFor(urlMatching("/my/resource/[a-z0-9]+"))
            .withRequestBody(matching(".*<message>1234</message>.*"))
            .withHeader("Content-Type", notMatching("application/json")));
}

You can also declare mappings in a more BDDish manner if you prefer:

givenThat(get(....

The above @Rule will restart the WireMock server before each test method. If you want your tests to run slightly faster the following code will keep WireMock running for the entire test class:

private static WireMockServer wireMockServer;

@BeforeClass
public static void setupServer() {
    wireMockServer = new WireMockServer();
    wireMockServer.start();
}

@AfterClass
public static void serverShutdown() {
    wireMockServer.stop();
}

@Before
public void init() {
    //Erases all stub mappings and recorded requests
    WireMock.reset();
}

All the API calls above are static methods on the com.github.tomakehurst.wiremock.client.WireMock class, so you'll need to add:

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
...

URL matching

For both stub mappings and verifications URLs can be matched exactly or via a regular expression:

.urlEqualTo("/exact/match")
.urlMatching("/match/[a-z]{5}")

Request method matching

HTTP methods currently supported are:

ANY, GET, POST, PUT, DELETE, HEAD, TRACE, OPTIONS 

Request header matching

WireMock will ignore headers in the actual request made that are not specified explicitly. So a mapping or verification with only one header specified will still match a request with three headers provided they contain the one specified and it matches.

Request headers can be matched exactly, with a regex or a negative regex:

.withHeader("Content-Type", equalTo("text/xml"))
.withHeader("Accept", matching("text/.*"))
.withHeader("etag", notMatching("abcd2134"))
.withHeader("etag", containing("abcd2134"))

Request body matching

Multiple match conditions can be specified for a request's body contents, in a similar fashion to headers:

.withRequestBody(equalTo("Something"))
.withRequestBody(matching(".*Something.*"))
.withRequestBody(notMatching(".*Another thing.*"))
.withRequestBody(containing("Some text"))

Every condition specified must be satisfied for the mapping to be selected (i.e. they're used with an AND operator)

Verifiying a precise number of requests

An alternate form of the verify call is:

verify(3, postRequestedFor(urlMatching("/my/resource/[a-z0-9]+")) ...

Running on a different host/port

If you'd prefer a different port, you can do something like this:

wireMockServer = new WireMockServer(80);
WireMock.configureFor("localhost", 80);

If you've deployed WireMock as a WAR somewhere and it's not at app server's root context:

WireMock.configureFor("somehost", 8086, "/wiremock"); 

Prioritising stub mappings

A stub mapping's priority can be set in the following way:

stubFor(get(urlEqualTo("/some/url")).atPriority(7) ...

Priority 1 is treated as most important. For stub mappings with the same priority the most recently inserted will be matched first.

Running as a proxy to another service

Stub mappings can be configured to proxy requests to another host and port. This can be useful if you want to run your app against a real service, but intercept and override certain responses. It can also be used in conjunction with the record feature described in the standalone section for capturing mappings from a session running against an external service.

Fault injection

WireMock stubs can generate various kinds of failure.

stubFor(get(urlEqualTo("/malformed/response")).willReturn(
            aResponse()
            .withFault(Fault.MALFORMED_RESPONSE_CHUNK)));

The com.github.tomakehurst.wiremock.http.Fault enum implements a number of different fault types.

Scenarios - Simulating Stateful Behaviour

Sometimes it is desirable to have different responses returned for the same request at different points in time. For instance given a to-do list resource, I might wish to simulate adding an item to an existing list and seeing the list updated e.g.

GET /organiser/todo-items (returns 1 item)
POST /organiser/todo-items (with 1 new item)
GET /organiser/todo-items (now returns 2 items)

A scenario is essentially a simple state machine, with a name and a state represented as a string (similar in concept to JMock's states feature). A stub mapping can be associated with a scenario, can depend on a particular state in order to be served, and can modify the scenario's state when served.

The behaviour described in the example above could be implemented like this:

stubFor(get(urlEqualTo("/organiser/todo"))
        .inScenario("ToDoList")
        .whenScenarioStateIs(Scenario.STARTED)
        .willReturn(aResponse().withBody("<item>Buy milk</item>")));

stubFor(put(urlEqualTo("/organiser/todo"))
        .inScenario("ToDoList")
        .whenScenarioStateIs(Scenario.STARTED)
        .willSetStateTo("First Item Added")
        .willReturn(aResponse().withStatus(204)));

stubFor(get(urlEqualTo("/organiser/todo"))
        .inScenario("ToDoList")
        .whenScenarioStateIs("First Item Added")
        .willReturn(aResponse().withBody("<item>Buy milk</item><item>Pay newspaper bill</item>")));

To return all registered scenarios back to the initial state you can call

WireMock.resetAllScenarios();

JSON API

Registering stub mappings

New stub mappings can be registered on the fly by posting JSON to http://localhost:8080/__admin/mappings/new :

{ 
    "priority": 3, // Defaults to 5 if not specified. 1 is highest.     
    "scenarioName": "ToDoList", // See scenario section above for details of this and the two following fields
    "requiredScenarioState": "Started",
    "newScenarioState": "First Item Added",                                         
    "request": {                                    
        "method": "GET",                        
        "url": "/my/other/resource", // use one of url or urlPattern
        "urlPattern": "/my/resource?startDate=.*&endDate=.*",
        "headers": {
            "Content-Type": {
                "equalTo": "text/xml"
            },
            "Accept": {
                "matches": "(.*)xml(.*)"
            },
            "Etag": {
                "doesNotMatch": "s0912lksjd(.+)"
            } 
        },
        "bodyPatterns": [
            { "equalTo": "<content>blah</content>" },
            { "contains": "blah" },
            { "matches": "<content>[a-z]+</content>" },
            { "doesNotMatch": ".*blab.*" }
        ]
    },                                      
    "response": {                                   
        "status": 200,  // Required                     
        "body": "YES INDEED!", // Specify this OR bodyFileName
        "bodyFileName": "path/to/mybodyfile.json", // Relative to __files
        "headers": {
            "Content-Type": "text/plain",
            "Cache-Control": "no-cache"
        },
        "fixedDelayMilliseconds": 500,
        "proxyBaseUrl": "http://someotherservice.com/root", // If you use this, exclude all other response attributes
        "fault": "EMPTY_RESPONSE" // If you use this, exclude all other response attributes
    }                                               
}

In the request portion only the method, and either the url or urlPattern attributes are mandatory. In the response portion only the status attribute is mandatory unless proxyBaseUrl or fault is specified, in which case all attributes except fixedDelayMilliseconds will be ignored.

Counting requests matching a pattern

Getting the number of requests that have been made to the server matching a pattern (since startup or last reset) can be achieved by posting JSON to http://localhost:8080/__admin/requests/count :

{                               
    "method": "POST",                       
    "url": "/resource/to/count",
    "headers": {
        "Content-Type": {
            "matches": "(.*)xml(.*)"
        }
    }
}

This will return a response of the form:

{ "count": 4 }

Resetting the server

A post to http://localhost:8080/__admin/reset will clear the list of logged requests and all stub mappings.

Resetting the state of all scenarios

A post to http://localhost:8080/__admin/scenarios/reset will return all scenarios' state to Started.

Global settings

Global settings can be updated by posting to /__admin/settings. Currently only one property is supported:

{                                               
    "fixedDelay": 2000
}

This will add the specified delay in milliseconds to every response.

Running standalone

Command line

WireMock can be run in its own process:

java -jar wiremock-1.18-standalone.jar

Or on an alternate port:

java -jar wiremock-1.18-standalone.jar --port 9999

Logging

Verbose logging can be enabled with the --verbose option.

Recording requests

If WireMock is started with the --record-mappings option non-admin requests will be captured under the mappings directory, with body content for each mapping captured under __files. A stub for a particular request will only be captured once within the current session (to avoid duplicates) and only for requests whose response was proxied. In practice this means that you can run wiremock as a proxy to your client application with recording turned on, and it will only record mappings for requests it doesn't already recognise.

You can use this option with the --proxy-all="http://someotherhost.com/root" parameter, which will proxy all requests to the given URL.

Files and mappings directories

The following directories will be created when you first start WireMock:

mappings - Contains stub mappings to load at startup. Any .json file containing a valid stub mapping (as described in the JSON API) placed under here will be loaded.

__files - Contains body content files referenced by mappings with bodyFileName element. Also files under here will be served by the web server directly, even when no mapping refers to them. However, mappings for a given URL will always take precedence.

Deploying as a WAR

WireMock can be built into a WAR file and deployed to other servlet containers. See the sample-war sub-project under WireMock's source for an example of how to do this.

Note: currently the default serving of files from __files when there is no mapping present won't work in this mode, so you'll need to make your own provisions if you still need this. Also fault responses won't work as they depend specifically on framework classes in Jetty.

Something went wrong with that request. Please try again.