Key takeaways
- WireMock lets you produce failures a real API will not give you on demand: timeouts, 500s, malformed bodies.
- Negative paths are where most production incidents live and where coverage is usually thinnest.
- Pin stubs to the real contract so a provider change breaks the test rather than production.
Why do we need to mock APIs ?
A lot of times when you develop integration tests there is a need to mock different APIs to test for negative cases to check how the rest of the platform behaves in that case and it is not feasible to change the API to return errors. This is especially true when you are trying to run the tests against a staging environment which simulates exactly the Production environment.
In these cases we can use WireMock to mock different APIs and to make the API return exactly what response we need for our tests.
Below we are going to run WireMock as a standalone server not as a Gradle or Maven dependency.
How to install WireMock ?
This post was written in 2018 for WireMock 2.14.0. The commands below use WireMock 3.13.2, the current stable release in November 2026, which moved to the org.wiremock Maven group (wiremock.org and Maven Central, November 2026).
1. Read the standalone guide: https://wiremock.org/docs/standalone/java-jar/
2. Download the standalone jar from: https://repo1.maven.org/maven2/org/wiremock/wiremock-standalone/3.13.2/wiremock-standalone-3.13.2.jar
3. After the jar has downloaded, open a terminal in the folder where it was saved and run:
java -jar wiremock-standalone-3.13.2.jar
4. In the terminal you should see something like below (this output is from the 2018 version; 3.x prints a different banner):
➜ wiremock java -jar wiremock-standalone-2.14.0.jar
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
port: 8080
enable-browser-proxying: false
no-request-journal: false
verbose: false
5. By the default the server will start on port 8080
6. Next we are going to create a mapping for our API using the JSON configuration.
For this we are going to create a JSON file myApi.json with the following contents:
{
"request": {
"method": "GET",
"url": "/myApi"
},
"response": {
"status": 200,
"body": "My API custom response\n"
}
}
7. We are going to place the file in the mappings folder that was created next to the WireMock jar.
8. Restart the WireMock server by running java -jar wiremock-standalone-3.13.2.jar.
9. Now browse to http://localhost:8080/test, a URL with no stub. WireMock answers “Request was not matched” and shows the closest stub, which confirms that the /myApi mapping was loaded:

10. Browsing to http://localhost:8080/myApi should respond with the configured response (status code 200 and with the body “My API custom response”)

Stubbing the negative cases
The 200 stub proves the setup works; the reason to run WireMock is the failures. Add more files to mappings. This one returns a server error:
{
"request": {
"method": "GET",
"url": "/myApi/error"
},
"response": {
"status": 500,
"body": "Internal Server Error"
}
}
This one answers correctly but only after 5 seconds, which is how you test your client’s timeout handling:
{
"request": {
"method": "GET",
"url": "/myApi/slow"
},
"response": {
"status": 200,
"body": "Slow response",
"fixedDelayMilliseconds": 5000
}
}
WireMock can also break the connection itself, for example with "fault": "CONNECTION_RESET_BY_PEER" or "fault": "EMPTY_RESPONSE" in the response (wiremock.org simulating faults guide, November 2026).
Frequently Asked Questions
Why mock an API you already have?
To produce the failures the real one will not give you on demand: timeouts, 500s, malformed bodies, a slow response. You cannot ask a staging dependency to break on cue, and those are exactly the paths that cause production incidents.
Do I need to add WireMock to my build?
Not for this. The standalone jar runs as its own server from the command line, which keeps the mock out of your application’s dependencies and lets other services point at it too.
How do I stop mocks from drifting away from the real API?
Pin the stubs to the real contract and check them against it. A mock that nobody verifies eventually describes an API that no longer exists, and then the tests pass while production fails.