SpringBoot WireMock

HOME

What is WireMock?

WireMock is a library for stubbing and mocking web services. It constructs a HTTP server that act as an actual web service. When a WireMock server is in action, we have the option to set up expectations, call the service, and then verify the behavior of service. It allows us to:-

  • Capture the incoming HTTP requests and write assertions for the captured HTTP requests.
  • Configure the response returned by the HTTP API when it receives a specific request.
  • Identify the stubbed and/or captured HTTP requests by using request matching.
  • Configure request matchers by comparing the request URL, request method, request headers, cookies, and request body with the expected values.
  • Use WireMock as a library or run it as a standalone process.

Why do we need to Wiremock a SpringBoot Application

Suppose your SpringBoot Application calls an external application and this call to external service bear some cost. You can’t test the application without calling the external service, So in this case, we can use WireMock to mock the external application while testing the REST service that you are developing in SpringBoot.

Spring Cloud Contract WireMock

The Spring Cloud Contract WireMock modules allow us to use WireMock in a Spring Boot application.

To use WireMock in SpringBoot, add Maven dependency

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-contract-wiremock</artifactId>
	<scope>test</scope>
</dependency>

To use WireMock’s fluent API add the following import:

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

We can use JUnit  @Rules  to start and stop the server. To do so, use the WireMockRule convenience class to obtain options instance, as the following example shows:

@Rule
    public WireMockRule wireMockRule = new WireMockRule(options().port(8081));

Wiremock runs as a stub server, and you can register stub behavior by using a Java API or by using static JSON declarations as part of your test.

Let us take the example of Student SpringBoot Application. The Response JSON of Student is shown below.

Creating a first WireMock mock service

Let us create a simple wiremock service with return status code as 200 and statsus message as “OK”.

@SpringBootTest
public class Wiremock_Example {

	@Rule
	public WireMockRule wireMockRule = new WireMockRule(options().port(8081));

	@Test
	public void test() {
	 
       stubFor(get(urlPathEqualTo("/students"))
.willReturn(aResponse().withHeader("Content-Type", "application/json")
.withStatus(200).withStatusMessage("OK")));
	}
}
  1. options is imported from package static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
  2. @Rule & @Test are from junit
  3. WireMockRule is from com.github.tomakehurst.wiremock.junit.WireMockRule

The following code will configure a response with a status of 200 and status message of “OK” to be returned when the relative URL exactly matches /students (including query parameters). The body of the response will be “Tom” and Content-Type header will be sent with a value of application/json.

To create the stub described above via the JSON API, the following document can either be posted to http://<host&gt;:<port>/__admin/mappings or placed in a file with a .json extension under the mappings directory:

Dynamic port numbers

Wiremock has the facility to pick free HTTP and HTTPS ports in SpringBoot application, which is a good idea if we need to run the applications concurrently.

@ClassRule
public static WireMockClassRule wiremock = new WireMockClassRule(
			WireMockSpring.options().dynamicPort());

Below is an example which shows how you can mock an applictaion on dynamic ports. In the below example, the localhost port is dynamic here (57099).

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class Wiremock_Example {

	@Rule
	public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort());

	@Test
	public void test() {
         stubFor(get(urlPathEqualTo("/students")).willReturn(aResponse()
.withHeader("Content-Type", "application/json")
.withStatus(200).withStatusMessage("OK").withBody("Tom")));
	}
}

How to run and test Mock Service?

In the below example, I will use Rest Assured tests to validate the behaviour of Mock Service. First, I need to get the mock service up and running and then use it in a test.

@SpringBootTest
public class Wiremock_Example {

	@Rule
	public WireMockRule wireMockRule = new WireMockRule(options().port(8089));

	public void setupMockService() {
		wireMockRule.stubFor(get(urlPathEqualTo("/students"))
.willReturn(aResponse().withHeader("Content-Type", "application/json")
.withStatus(200).withStatusMessage("OK")));
	}

	@Test
	public void positiveTest() {
		setupMockService();
   
        given()
       .when()
            .get("http://localhost:8089/students")
       .then()
            .assertThat().statusCode(200);
	}
}

In the below example, it is shown that the response content of a wiremock service can also be verified.

@SpringBootTest
public class Wiremock_Example {

	@Rule
	public WireMockRule wireMockRule = new WireMockRule(options().port(8090));

	public void setupMockService() {

		wireMockRule.stubFor(get(urlPathEqualTo("/students"))
.willReturn(aResponse().withHeader("Content-Type", "application/json")
.withStatus(200).withStatusMessage("OK").withBody("Tom")));
	}

	@Test
	public void responseMessageTest() {

		setupMockService();
		 
         given()
        .when()
            .get("http://localhost:8090/students")
        .then()
           .assertThat().body(containsString("Tom"));
	}
}

How to read response body from a file?

To read the body content from a file, place the file under the  __files directory under src/test/resources when running from the JUnit rule.To make your stub use the file, use withBodyFile() on the response builder with the file’s path relative to __files.

public class Wiremock_Example {

	@Rule
	public WireMockRule wireMockRule = new WireMockRule(options().port(8085));

	public void setupMockService() {

		wireMockRule.stubFor(get(urlPathEqualTo("/students"))
.willReturn(aResponse().withHeader("Content-Type", "application/json")						.withStatus(200).withStatusMessage("OK").withBodyFile("Response.json")));
	}

	@Test
	public void responseFileTest() {

		setupMockService();

		given()
       .when()
           .get("http://localhost:8085/students").then()
       .assertThat()
           .body(containsString("John"));
	}
}

To read more about SpringBoot Wiremock, you can refer SpringBoot Wiremock website.

One thought on “SpringBoot WireMock

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s