Getting started with: WireMock

This is the seventh article in our series on new, popular or otherwise interesting tools used in test automation. You can read all posts within this series by clicking here.

What is WireMock?
From the WireMock.org website: WireMock is a flexible library for stubbing and mocking web services. Unlike general purpose mocking tools it works by creating an actual HTTP server that your code under test can connect to as it would a real web service. It supports HTTP response stubbing, request verification, proxy/intercept, record/playback of stubs and fault injection, and can be used from within a unit test or deployed into a test environment. Although it’s written in Java, there’s also a JSON API so you can use it with pretty much any language out there.

In short, WireMock is a very handy tool for all those situations where you need to set up a mock version of a web service, for example for testing or development purposes.

Where can I get WireMock?
WireMock can be downloaded from the WireMock Maven repository.

How do I install and configure WireMock?
Installing WireMock is as simple as downloading the latest standalone version from the WireMock Maven repository and adding it as a dependency to your Java project.

Creating a first WireMock mock service
Let’s start by creating a very simple mock service that returns a plain text string and a HTTP status code.

public void setupStub() {
		
	stubFor(get(urlEqualTo("/an/endpoint"))
            .willReturn(aResponse()
                .withHeader("Content-Type", "text/plain")
                .withStatus(200)
                .withBody("You've reached a valid WireMock endpoint")));
}

This code snippet creates a simple mock service that runs at the /an/endpoint endpoint on the WireMock server (your localhost most of the time, but more about that in a bit). It returns a response with content type text/plain, HTTP status 200 and body text “You’ve reached a valid WireMock endpoint“.

Running and testing your mock service
Of course, we would also like to validate whether the mock service we created does what we told it to do. In this post, I will use JUnit-based REST Assured tests to validate the behaviour of our mocks. But first, we need to get our mock service up and running before we start testing. This can be done very easily with WireMock using a JUnit @Rule:

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

This rule starts and stops the mocks defined in your JUnit test class for every test in it. Next, we can define a couple of REST Assured tests to see whether the mock service is doing what we expect:

@Test
public void testStatusCodePositive() {
		
	setupStub();
		
	given().
	when().
		get("http://localhost:8090/an/endpoint").
	then().
		assertThat().statusCode(200);
}
	
@Test
public void testStatusCodeNegative() {
	
	setupStub();
		
	given().
	when().
		get("http://localhost:8090/another/endpoint").
	then().
		assertThat().statusCode(404);
}
	
@Test
public void testResponseContents() {
		
	setupStub();
	
	String response = get("http://localhost:8090/an/endpoint").asString();
	Assert.assertEquals("You've reached a valid WireMock endpoint", response);
}

When we run these tests, they will all pass, indicating our mock service behaves as expected:
WireMock JUnit test results

Request-response matching
WireMock also allows you to define a stub that returns a particular answer based on (part of) the request message using the matching matcher method:

public void setupStub() {
		
	stubFor(post(urlEqualTo("/pingpong"))
			.withRequestBody(matching("<input>PING</input>"))
            .willReturn(aResponse()
                .withStatus(200)
                .withHeader("Content-Type", "application/xml")
                .withBody("<output>PONG</output>")));
}

This service only returns a status code 200 and a response XML message when the request body equals a given value. Again, we can validate this easily using REST Assured:

@Test
public void testPingPongPositive() {
		
	setupStub();
		
	given().
		body("<input>PING</input>").
	when().
		post("http://localhost:8090/pingpong").
	then().
		assertThat().
		statusCode(200).
		and().
		assertThat().body("output", org.hamcrest.Matchers.equalTo("PONG"));
}

WireMock also allows you to use regular expressions for more flexible request matching.

Creating stateful mocks
As a final example, I’ll show how to create a stateful mock. This is done in WireMock using scenarios:

public void setupStub() {
		
	stubFor(get(urlEqualTo("/todolist"))
			.inScenario("addItem")
			.whenScenarioStateIs(Scenario.STARTED)
			.willReturn(aResponse()
                .withStatus(200)
                .withHeader("Content-Type", "application/xml")
                .withBody("<list>Empty</list>")));
		
	stubFor(post(urlEqualTo("/todolist"))
			.inScenario("addItem")
			.whenScenarioStateIs(Scenario.STARTED)
			.willSetStateTo("itemAdded")
			.willReturn(aResponse()
				.withHeader("Content-Type", "application/xml")
                .withStatus(201)));
		
	stubFor(get(urlEqualTo("/todolist"))
			.inScenario("addItem")
			.whenScenarioStateIs("itemAdded")
			.willReturn(aResponse()
                .withStatus(200)
                .withHeader("Content-Type", "application/xml")
                .withBody("<list><item>Item added to list</item></list>")));	
}

So, when we first perform a GET on this mock, an empty to-do list is returned. Then, when we do a POST, the mock service state is changed from Scenario.STARTED (a default in WireMock) to “itemAdded“. Then, when we do another GET, we get a to-do list with a single item on it:

@Test
public void testStatefulMock() {
		
	setupStub();
		
	given().
	when().
		get("http://localhost:8090/todolist").
	then().
		assertThat().
		statusCode(200).
		and().
		assertThat().body("list", org.hamcrest.Matchers.equalTo("Empty"));
		
	given().
	when().
		post("http://localhost:8090/todolist").
	then().
		assertThat().
		statusCode(201);
		
	given().
	when().
		get("http://localhost:8090/todolist").
	then().
		assertThat().
		statusCode(200).
		and().
		assertThat().body("list", org.hamcrest.Matchers.not("Empty")).
		and().
		assertThat().body("list.item", org.hamcrest.Matchers.equalTo("Item added to list"));
}

A trivial example, perhaps, but nevertheless it shows you how can create stateful mocks easily using WireMock.

Further reading
WireMock provides many more useful features for creating just the mock you want. A complete reference guide can be found on the WireMock website.

An Eclipse project including the mock services and REST Assured tests I’ve used in this post can be downloaded here.

52 thoughts on “Getting started with: WireMock

  1. Hi,
    Thanks for the tutorial. I tried your demo and got this error:

    org.apache.http.conn.HttpHostConnectException: Connect to localhost:8080 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused

    (Sorry that this comment doesn’t allow me to attach the screenshot)

    Looks like the wiremock server doesn’t fire up. Can you tell me more specific step by step to run you demo. Thanks

      • Hi
        No. I don’t think other application running on port 8090.

        So the following line will start up Wiremock server??:
        @Rule
        public WireMockRule wireMockRule = new WireMockRule(8090);

        I used maven for the project and here’s my pom.xml:

        4.0.0

        net.henrydang
        wiremock-demo
        1.0-SNAPSHOT

        com.github.tomakehurst
        wiremock
        1.57

        org.testng
        testng
        6.8
        test

        com.jayway.restassured
        rest-assured
        2.9.0

          • Hi Guich,

            No, I haven’t looked into it to be honest. I’m planning on working with WireMock a lot more in the near future so hopefully I’ll get round to it soon. Can’t promise anything unfortunately.

  2. Hi,

    I actually going through your site and just started working on the wiremock, your tutorial is very helpful.
    I try to use the code as it is in my Eclipse. I have configured all the jars as well import all packages. But still getting error in Line
    given().
    String response = get(“http://localhost:8090/an/endpoint”).asString();
    could u please helpme out.

    • Hi Bindu,

      First of all: have you included the REST Assured library as well, and also the static imports it requires?

      Second, if that’s literally your code, it’s written incorrectly. You can’t do a variable declaration right after the given().

      Hope that helps! If not, please send your full class code to bas@ontestautomation.com and I’ll have a closer look.

      • Hi Bas,

        I am able to execute the above demo of the wiremock. Junit testing works fine in case when i haven’t started the server, in case when i started the server and after that execute the above code getting the following error.
        [main] ERROR WireMock – failed DelayableSocketConnector@0.0.0.0:8080: java.net.BindException: Address already in use: JVM_Bind
        [main] ERROR WireMock – failed Server@6c3e459e: java.net.BindException: Address already in use: JVM_Bind

        Seems like wiremock server doesn’t fire up.

    • Hi Maurice,

      Of course that’s OK! Thanks for your contribution.

      I have recently started to provide my code samples as Maven projects so people can import them in IDEs other than Eclipse as well. Will probably start providing them through GitHub in the near future instead of as download links.

  3. Hi,

    I am going through your acticle. And I try using your code in intellij.
    I have configured “rest-assured”. But still getting error in Line
    then().
    It seems that the jar I used doesn’t support then.

    • Hi Nancy,

      if the library used supports given() and when() it should also support then(), so I think it’s likely the error is somewhere else. Could you please post the full code of your test, or email it to bas@ontestautomation.com? I’d like to have a look at it.

      • Hi Bas,

        Thanks for your help. At last I modified the cased as below:
        import org.junit.Test;

        import static com.github.tomakehurst.wiremock.client.WireMock.*;
        import static com.jayway.restassured.RestAssured.given;
        import static junit.framework.Assert.assertTrue;

        public class mock {
        public void setupStub() {
        stubFor(get(urlEqualTo(“/an/endpoint”))
        .willReturn(aResponse()
        .proxiedFrom(“http://baidu.com”)
        .withHeader(“Content-Type”, “text/plain”)
        .withStatus(200)
        .withBody(“You’ve reached a valid WireMock endpoint”)));
        }

        // @Rule
        // public WireMockRule wireMockRule = new WireMockRule(8090);

        @Test
        public void testStatusCodePositive() {

        setupStub();

        int statusCode = given().
        when().
        get(“http://baidu.com/an/endpoint”).
        andReturn().getStatusCode();
        assertTrue(statusCode == 200);
        }
        }

        And it can be passed.

  4. Bas,
    I’m wondering how can I run the mocked service as a separated service? And then other service can call it.

    Best regards,
    Nancy

    • Hi Ravi,

      I don’t think that would be any different from mocking any other API, as long as you know what the contract for that third party API looks like and you have control over the endpoint your rest API consumes.

      • Here is my issue. I have a Andriod app calling a restAPI(ownAPI.domain.com/item/search) hosted on a VM in cloud (load balanced). the restAPI internally calls another API(otherAPI.Otherdomain.com) hosted on different VM in cloud(load balanced).

        I need to automate my UI testing. I cannot guarantee the data from the API on otherAPI.Otherdomain.com. I am trying to mock the call.

        I am trying to mock by running a standalone mock instance. With out changing by code how can I get the API call on otherAPI.Otherdomain.com return my mock data. Any thing I have to add in the mappings, files folders for wiremock

        Is there a better way to get that done?

        Thank you
        Ravi

        • Thinking out of the box here, but is mocking your own API an option? In that way you still have full control over the data your app sends / retrieves.

          • I was able to get that done. I was trying to have real time call to my API so business logic can be tested as well. I just want the mock data from the dependent service.

            I have unit tests that test each method in my API

            -Ravi

          • Understood. Can you somehow configure your own API to talk to a different endpoint? Or is that hard wired into the code?

  5. I understand where u are going with this. I was also trying that using NGNIX proxy. so I do not have to change anything in the code/config but use NGNIX to route to a local endpoint so WIREMOCK can intercept it.

    -Ravi

      • Yes I have seen that. It is more like a reverse proxy. The Wiremock routes any requests coming in with a certain path to a different server.

        I am looking for when a request is going out to be routed back localhost or to send mock data.

        • I see. My previous question still stands: do you have the option of redefining the endpoint of the other API in your own API? Or is that hard coded? If it’s configurable you could simply spin up a WireMock mock and reroute the outgoing traffic from your own API to it.. Or am I missing something?

  6. How to group multiple requests in one file. I am creating test cases so I can group into files. I am saving one request per one file. I want to save multiple requests in one file and do the same for another file.

  7. Hello Bas,

    just one another question; how can you verify the contract between mock and real API? Do you call the real API as a next step or how can you be sure, that you mock is yet correct

    • Hey Alex,

      that’s a very good question. Personally, when I use mocks or service virtualization, I like to make sure that my mock or virtual asset is indeed exerting the right behavior. I usually write some tests for them, which I first run against the real API and then against the mock. If both pass, they should be fine.

      For example: I’m currently working on a REST Assured workshop where I previously used a live API to write tests against. Of course, during the actual workshop the API was not available.. To prevent this from happening in the future, I am replacing the API calls with WireMock mocks. If the tests still pass, the mocks work as intended. If they don’t, I have some more work to do..

      Hope that is useful for you.

  8. Do you think is serious you post only an Eclipse project? Use maven, use gradle but for god’s sake don’t force us to use that crappy Eclipse shit

    • Thanks for your feedback. All my recent posts feature Maven projects, and I’m sure you’re more than capable enough to import the sources into your own tool stack of choice.

  9. Hello, I really liked your tutorial. Thank you!
    I have tests written in restAssured. When a test is running, internally a call is made to 3rd party api. I want to use the record and play feature of wire mock. I want to record all the requests and responses made to these 3rd party APIs so I can mock this service.
    How can I do this using wire mock?

    • Hey Priya,

      in that case, you could try and run WireMock standalone in record and playback mode, as described here. Using the command line argument you can specify for which domain (search.twitter.com in the example) you want to capture the responses. Then it’s a matter of configuring your API that calls the third party API to call the WireMock proxy instead, after which WireMock would capture the requests/responses passing through it..

      Hope that helps!

Leave a Reply

Your email address will not be published. Required fields are marked *