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.

My article on service virtualization has been published on StickyMinds

On August 10th StickyMinds, a popular online community for software development professionals, published an article I wrote titled ‘Four ways to boost your testing process with service virtualization’. In this article, I describe a case study from a project I worked on recently, where service virtualization was used to significantly improve the testing process.

The article demonstrates (as you can probably guess from the title) how you too can employ service virtualization to remove some of the bottlenecks associated with testing and test data and test environment management for distributed systems and development processes.

You can read the article by visiting the StickyMinds homepage now. The article will be right there on the front page.

StickyMinds

Please let me know what you think in the comments! Also, feel free to share the article with your connections on social media.

Again, the article can be read here.

Stubs, mocks or virtual assets?

If, during the software development process, you stumble upon the need to access software components that:

  • Have not yet been developed,
  • Do not contain sufficient test data,
  • Require access fees, or
  • Are otherwise constrained with regards to accessibility,

there are several options you may consider to work around this issue. In this post, I will introduce three options and explain some of the most important of their characteristics.

Please note that the terms ‘stub’ and ‘mock’ are often mixed up in practice, so what is defined as a mock here might be called a stub somewhere else and vice versa. However, I tried to use definitions that are more or less agreed upon in the development and testing community.

Stubs
The simplest form of removing dependency constraints is the use of stubs. A stub is a very simple placeholder that does pretty much nothing besides replacing another component. It provides no intelligence, no data driven functionality and no validations. It can be created quickly and is most commonly used by developers to mimick behaviour of objects and components not available in their development environment.

Mocks
Mocks contain a little more intelligence compared to stubs. They are commonly configured to be used for specific test or development purposes. They are used to define and verify expectations with regards to behaviour. For example, a mock service might be configured to always return certain test data in response to a request recevied, so that specific test cases can be executed by testers. The difference between mocks and stubs from a testing perspective can be summarized by the fact that a mock can cause a test case to fail, whereas a stub can’t.

Virtual assets
Virtual assets are simulated components that closely mimic the behaviour of ‘the real thing’. They can take a wide variety of inputs and return responses that their real-life counterpart would return too. They come with data driven capabilities that allow responses (and therefore behaviour) to be configured on the fly, even by people without programming knowledge. Virtual assets should also replicate connectivity to the simulated component by applying the same protocols (JMS, HTTP, etc.) and security configuration (certificates, etc.). The application of virtual assets in test environments is commonly called service virtualization.

Testing terms related to stubs and mocks

If you want to read more about component or API stubbing, mocking or virtualization, this page in the SmartBear API Testing Dojo provides an interesting read. Also, Martin Fowler wrote a great piece on mocks and stubs on his blog back in 2007.