This blog post describes how we can configure the system under test when we want to use WireMock with JUnit 5 and we don't want to use a custom JUnit 5 extension. After we have finished this blog post, we:
- Understand how we can configure the used WireMock server.
- Know how we can start the WireMock server before a test method is run.
- Can stop the WireMock server after a test method has been run.
Let's begin.
Configuring the WireMock Server
If we want to configure the WireMock server from the scratch, we have to create a new com.github.tomakehurst.wiremock.WireMockServer
object. However, before we can do this, we have to create a new test class and add a WireMockServer
field to the created class.
After we have created our test class, its source code looks as follows:
import com.github.tomakehurst.wiremock.WireMockServer; class WireMockConfigurationTest { private WireMockServer wireMockServer; }
Because we want to write isolated test methods, we have to ensure that every test method gets its own WireMockServer
object. This means that we we have to create the required WireMockServer
object in a setup method that is invoked before a test method is run.
After we have added this setup method to our test class, its source code looks as follows:
import com.github.tomakehurst.wiremock.WireMockServer; import org.junit.jupiter.api.BeforeEach; class WireMockConfigurationTest { private WireMockServer wireMockServer; @BeforeEach void configureSystemUnderTest() { //Create and configure the WireMockServer } }
Next, we will take a look at four examples which demonstrate how we can use the most common configuration options of WireMock.
Example 1: The Default Configuration
If we want to use the default configuration, we can create a new WireMockServer
object by simply using its no-argument constructor. After we have created the required WireMockServer
object, the source code of our test class looks as follows:
import com.github.tomakehurst.wiremock.WireMockServer; import org.junit.jupiter.api.BeforeEach; class WireMockConfigurationTest { private WireMockServer wireMockServer; @BeforeEach void configureSystemUnderTest() { this.wireMockServer = new WireMockServer(); } }
This configuration creates a WireMock server that listens to all local IPv4 addresses (0.0.0.0) and the port 8080.
If we want to provide custom configuration to the created WireMockServer
object, we have to use the constructor that takes an com.github.tomakehurst.wiremock.core.Options
object as a constructor argument. We can create new Options
objects by using the fluent API provided by the com.github.tomakehurst.wiremock.core.WireMockConfiguration
class.
The next three examples demonstrate how we can provide custom configuration to our WireMock server.
Example 2: Using a Custom IP Address
If we want to change the local IPv4 address that is listened by the created WireMock server, we have to configure the used IPv4 address by using the bindAddress()
method of the WireMockConfiguration
class. After we have changed the listened IPv4 address, the source code of our test class looks as follows:
import com.github.tomakehurst.wiremock.WireMockServer; import org.junit.jupiter.api.BeforeEach; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; class WireMockConfigurationTest { private WireMockServer wireMockServer; @BeforeEach void configureSystemUnderTest() { this.wireMockServer = new WireMockServer(options() .bindAddress("127.0.0.1") ); } }
Example 3: Using a Custom Port
If we want to change the port that is listened by the created WireMock server, we have to configure the new port by using the port()
method of the WireMockConfiguration
class. After we have changed the listened port, the source code of our test class looks as follows:
import com.github.tomakehurst.wiremock.WireMockServer; import org.junit.jupiter.api.BeforeEach; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; class WireMockConfigurationTest { private WireMockServer wireMockServer; @BeforeEach void configureSystemUnderTest() { this.wireMockServer = new WireMockServer(options() .port(9090) ); } }
Example 4: Using a Dynamic Port
If we cannot guarantee that a specific port is free when we run our tests, we can configure WireMock to find a free port before it starts the WireMock server. We can do this by using the dynamicPort()
method of the WireMockConfiguration
class. After we have configured WireMock to use a dynamic port, the source code of our test class looks as follows:
import com.github.tomakehurst.wiremock.WireMockServer; import org.junit.jupiter.api.BeforeEach; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; class WireMockConfigurationTest { private WireMockServer wireMockServer; @BeforeEach void configureSystemUnderTest() { this.wireMockServer = new WireMockServer(options() .dynamicPort() ); } }
We can now use the most common configuration options of WireMock. Let's move on and find out how we can start our WireMock server.
Starting the WireMock Server
Before we can write tests which use WireMock, we have to start our WireMock server. Because our configuration ensures that every test method gets its own WireMock server, we have to start the WireMock server in the setup method that creates a new WireMockServer
object. We can start our WireMock server by invoking the start()
method of the WireMockServer
class.
After we have ensured that our WireMock server will be started before a test method is run, the source code of our test class looks as follows:
import com.github.tomakehurst.wiremock.WireMockServer; import org.junit.jupiter.api.BeforeEach; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; class WireMockConfigurationTest { private WireMockServer wireMockServer; @BeforeEach void configureSystemUnderTest() { this.wireMockServer = new WireMockServer(options() .dynamicPort() ); this.wireMockServer.start(); } }
Next, I want to make a quick note about using the started WireMock server.
A Quick Note About Using the WireMock Server
Even though the next parts of my WireMock tutorial will describe how we can write tests which use WireMock, I want to point out one very important thing. After we have started our WireMock server, we can use WireMock by using one of these two options:
First, we can use the methods of the WireMockServer
class. This approach works even if we have changed the configuration of our WireMock server.
Second, we can use the static
methods of the WireMock
class that provides an over-the-wire client to a WireMock server. However, if we have changed the host and/or the port that of the started WireMock server and we want use this approach, we have to provide the new host and/or port to the over-the-wire client by using the static configureFor()
method of the WireMock
class.
For example, if we are using a dynamic port and we want to use the over-the-wire client, we have to configure the port that is listened by our WireMock server. After we have done this, the source code of our test class looks as follows:
import com.github.tomakehurst.wiremock.WireMockServer; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; class WireMockConfigurationTest { private WireMockServer wireMockServer; @BeforeEach void configureSystemUnderTest() { this.wireMockServer = new WireMockServer(options() .dynamicPort() ); this.wireMockServer.start(); configureFor(this.wireMockServer.port()); } }
configureFor()
method in every test class which uses the over-the-wire client. Otherwise our tests can fail because the over-the-wire client cannot connect to the WireMock server.Let's move on and find out how we can stop our WireMock server.
Stopping the WireMock Server
Because we want to free all resources that are reserved before a test method is run, we have to stop our WireMock server in a teardown method that is run after a test method has been run. We can stop our WireMock server by invoking the stop()
method of the WireMockServer
class.
After we have ensured that our WireMock server will be stopped after a test method has been run, the source code of our test class looks as follows:
import com.github.tomakehurst.wiremock.WireMockServer; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; class WireMockConfigurationTest { private WireMockServer wireMockServer; @BeforeEach void configureSystemUnderTest() { this.wireMockServer = new WireMockServer(options() .dynamicPort() ); this.wireMockServer.start(); } @AfterEach void stopWireMockServer() { this.wireMockServer.stop(); } }
We can now configure the system under test from the scratch when we are writing tests which use WireMock with JUnit 5. Let's summarize what we learned from this blog post.
Summary
This blog post has taught us four things:
- We can configure our WireMock server when we create a new
WireMockServer
object. - We have to start our WireMock server in the setup method that is invoked before a test method is run.
- If we want to use the over-the-wire client provided by the
WireMock
class and we have changed the configuration of our WireMock server, we have to configure the over-the-wire client by using thestatic configureFor()
method of theWireMock
class. - We have to stop our WireMock server in the teardown method that is invoked after a test method has been run.
P.S. You can get the example application of this blog post from Github.
There is also a C# .NET version available (WireMock.Net) which can be used for .NET unit-testing.
More details can be found here : https://github.com/WireMock-Net/WireMock.Net
Awesome. Are you behind this testing tool? If so, keep up the good work.
Yes indeed, this is my project.
If you have any questions or new ideas, please create an issue or chat in gitter.
I have also created one mock service but i got one requirement from some one -
In my service all things work via a configuration file which has key and value pair similar to json syntax where you give API details.
But requirement is some one want to create these details at run time.How it is done in wire mock like at run time how i can add a new API endpoint and other details