WireMock is a tool for mocking HTTP-based APIs that runs in the unit tests, on the desktop, or in the test environment. Read more about WireMock in this article: Introduction to WireMock. One of the most important features of WireMock is Request Matching. WireMock supports matching of requests to stubs and verification queries using the following attributes: URL, HTTP Method, Query parameters, Headers, Cookies, Request body, etc. So in this article, we are going to see how Request Matching works with JUnit Test in WireMock.
Prerequisites:
- Refer to this article and install WireMock on your local machine: How to Download and Install WireMock?
- How to Use WireMock with JUnit Test?
1. URL Matching
In WireMock, the URLs can be matched either by equality or by regular expression. And you can match just the path of the URL or the path and query together. Let’s see both scenarios with examples.
Example: Equality matching on the path only
Syntax:
urlPathEqualTo("/your/url")
Now let’s demonstrate this with the help of IntelliJ IDEA as the IDE and Maven as the build tool.
Example Project
Step 1: Refer to this article How to Create a Maven Project in IntelliJ IDEA and create a Maven project in IntelliJ IDEA.
Step 2: Add the following dependencies in your pom.xml file.
<!-- Dependency for okhttp --> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>4.2.2</version> </dependency> <!-- Dependency for Wiremock--> <dependency> <groupId>com.github.tomakehurst</groupId> <artifactId>wiremock</artifactId> <version>2.27.2</version> <scope>test</scope> </dependency> <!-- Dependency for JUnit--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13-rc-2</version> <scope>test</scope> </dependency>
Below is the complete code for the pom.xml file.
XML
<? xml version = "1.0" encoding = "UTF-8" ?> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 < modelVersion >4.0.0</ modelVersion > < groupId >org.example</ groupId > < artifactId >wiremock-with-junit</ artifactId > < version >1.0-SNAPSHOT</ version > < properties > < maven.compiler.source >11</ maven.compiler.source > < maven.compiler.target >11</ maven.compiler.target > </ properties > < dependencies > < dependency > < groupId >com.squareup.okhttp3</ groupId > < artifactId >okhttp</ artifactId > < version >4.2.2</ version > </ dependency > < dependency > < groupId >com.github.tomakehurst</ groupId > < artifactId >wiremock</ artifactId > < version >2.27.2</ version > < scope >test</ scope > </ dependency > < dependency > < groupId >junit</ groupId > < artifactId >junit</ artifactId > < version >4.13-rc-2</ version > < scope >test</ scope > </ dependency > </ dependencies > </ project > |
Step 3: Now go to the src > test > java and create a test class named WiremockWithJunit. In this class, we are going to perform the Request Matching with JUnit Test. At first, we have to configure the stub something like this.
private void configStubForPostMethod() { configureFor("localhost", 9090); stubFor(post(urlPathEqualTo("/testuser")) .willReturn(status(200) .withBody("Welcome TestUser!") .withHeader("content-type", "application/json"))); }
The code is self-explanatory, so please refer to the code in-depth so you can understand the code easily. Now let’s create the Request Body
RequestBody body = new FormBody.Builder() .add("username", "testuser") .build();
Then call the request in WireMock through OkHttpClient.
OkHttpClient client = new OkHttpClient().newBuilder() .build(); Request request = new Request.Builder() .url("http://localhost:9090/testuser") .method("POST", body) .build(); Response response = client.newCall(request).execute();
And finally, assert the response, and you are done
assertEquals("Welcome TestUser!", response.body().string());
Below is the complete code for the WiremockWithJunit.java class.
Java
import com.github.tomakehurst.wiremock.junit.WireMockRule; import okhttp3.*; import org.junit.Rule; import org.junit.Test; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import static org.junit.Assert.assertEquals; public class WiremockWithJunit { @Rule public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().port( 9090 )); // Stubbing with JUnit @Test public void stubbing_with_junit_test() throws Exception { // stub configuration configStubForPostMethod(); // Create the Request Body RequestBody body = new FormBody.Builder() .add( "username" , "testuser" ) .build(); // call request in WireMock through OkHttpClient OkHttpClient client = new OkHttpClient().newBuilder() .build(); Request request = new Request.Builder() .method( "POST" , body) .build(); Response response = client.newCall(request).execute(); // assert the response assertEquals( "Welcome TestUser!" , response.body().string()); } private void configStubForPostMethod() { configureFor( "localhost" , 9090 ); stubFor(post(urlPathEqualTo( "/testuser" )) .willReturn(status( 200 ) .withBody( "Welcome TestUser!" ) .withHeader( "content-type" , "application/json" ))); } } |
Now, let’s run our test. And in the below image you can see our test has been passed.
Example: Regex matching on the path only
Syntax:
urlPathMatching("/your/([a-z1-9]*)")
Now let’s demonstrate this with the help of IntelliJ IDEA as the IDE and Maven as the build tool. We are starting from Step 3 as Step 1 and Step 2 will remain similar.
Step 3: Now go to the src > test > java and create a test class named WiremockWithJunit. At first, we have to configure the stub something like this.
private void configStubForPostMethod() { configureFor("localhost", 9090); stubFor(post(urlPathMatching("/gfg/([a-z1-9]*)")) .willReturn(status(200) .withBody("Welcome TestUser!") .withHeader("content-type", "application/json"))); }
The code is self-explanatory, so please refer to the code in-depth so you can understand the code easily. Now let’s create the Request Body
RequestBody body = new FormBody.Builder() .add("username", "testuser") .build();
Then call the request in WireMock through OkHttpClient.
OkHttpClient client = new OkHttpClient().newBuilder() .build(); Request request = new Request.Builder() .url("http://localhost:9090/gfg/testuser234125") .method("POST", body) .build(); Response response = client.newCall(request).execute();
Note: Here in the URL you can put anything in the range of [a-z] and [1-9] after /gfg/.
And finally, assert the response, and you are done
assertEquals("Welcome TestUser!", response.body().string());
Below is the complete code for the WiremockWithJunit.java class.
Java
import com.github.tomakehurst.wiremock.junit.WireMockRule; import okhttp3.*; import org.junit.Rule; import org.junit.Test; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import static org.junit.Assert.assertEquals; public class WiremockWithJunit { @Rule public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().port( 9090 )); // Stubbing with JUnit @Test public void stubbing_with_junit_test() throws Exception { // stub configuration configStubForPostMethod(); // Create the Request Body RequestBody body = new FormBody.Builder() .add( "username" , "testuser" ) .build(); // call request in WireMock through OkHttpClient OkHttpClient client = new OkHttpClient().newBuilder() .build(); Request request = new Request.Builder() .method( "POST" , body) .build(); Response response = client.newCall(request).execute(); // assert the response assertEquals( "Welcome TestUser!" , response.body().string()); } private void configStubForPostMethod() { configureFor( "localhost" , 9090 ); stubFor(post(urlPathMatching( "/gfg/([a-z1-9]*)" )) .willReturn(status( 200 ) .withBody( "Welcome TestUser!" ) .withHeader( "content-type" , "application/json" ))); } } |
Similarly, you can also try the demonstration in your IntelliJ IDEA for the following Request Matching.
Equality matching on path and query
Syntax:
urlEqualTo("/your/url?and=query")
Regex matching on path and query
Syntax:
urlMatching("/your/([a-z]*)\\?and=query")
2. Matching Other Attributes
Apart from the URL, all request attributes can be matched using some operators.
Equality
Syntax:
.withHeader("Content-Type", equalTo("application/xml"))
Case-insensitive equality
Syntax:
.withHeader("Content-Type", equalToIgnoreCase("application/xml"))
3. JSON Equality
It will be a match if the attribute is valid JSON and is a semantic match for the expected value.
Syntax:
.withRequestBody(equalToJson("{ \"name\": "Lazyroar" }"))
4. XML Equality
It will be a match if the attribute value is valid XML and is semantically equal to the expected XML document.
Syntax:
.withRequestBody(equalToXml("<thing>Lazyroar</thing>"))
5. Basic Authentication Matching
In WireMock, you can also match on HTTP basic authentication.
Syntax:
stubFor(get(urlEqualTo("/basic-auth")).withBasicAuth("UserName", "Password")