WireMock, Cucumber, and Spring Boot
An Arc-E-Tect’s Software Engineering Done Right guide
Updated on February 25st, 2025 with WireMock’s Spring Boot support release 3.6.0.
A few weeks ago, I wrote this article explaining how to develop an API using WireMock, Cucumber, and Spring Boot. Since then, things have changed significantly, especially WireMock’s integration with Spring Boot and its support by Gradle. These changes compelled me to update this article.
If you have read the original article, feel free to skip ahead to the locations clearly marked as updated content. If you haven’t had the pleasure of reading it, just keep on reading and enjoy a full explanation of how you can use WireMock, Cucumber, and Spring Boot to develop APIs using Test Driven Development, Behavior Driven Development, and Consumer Contract Driven Development principles and practices. In short: API First.

Clap for this story when you liked the original text and are looking forward to read the update.
In today’s API-driven world, it is critical to guarantee that the users of your APIs have an experience without frustration as they consume those APIs. For this reason, experienced software engineers apply concepts such as Test-Driven Development, TDD, and Behavior-driven Development while delivering high-quality APIs. Tools like WireMock and Cucumber are indispensable, and frameworks like Spring Boot are key to reducing the cost of delivering software-based products.
Although there are plenty of resources available online that explain how to use WireMock and Spring Boot together or how to use Cucumber and Spring Boot together, there are only a few resources to be found that show precisely how to use all three of them in your software development process.
This article will explain how you can configure WireMock and Cucumber to develop your APIs in a truly API-First fashion while applying Test-Driven Development and Behavior-Driven Development practices to guarantee that your APIs are useful, usable, and according to specifications.
Before I detail how these three excellent tools and technologies can be configured to achieve a sum far greater than their parts, I will explain the concepts this trio supports. Although I elaborate on the concepts covered in this article, I assume that you are already familiar with the tools and technologies mentioned in the article’s title: WireMock, Cucumber, and Spring Boot.
The concepts
The concepts, tools, and technologies discussed in this article are covered in detail in my book “Software Engineering Done Right — the practice of delivering useful and usable software”. You can request access to the electronic version of the book through my Discord server:
Test-Driven Development
Test-Driven Development, or TDD, is the practice of developing software by first developing a test to validate the correctness of the software and second developing the software itself. Thus, the software is guaranteed to be testable and tested.
Besides the benefit of having automated tests for practically every feature you develop, it also adds the advantage of having clarity on the requirements related to the feature. Unless the requirements are clear, developing or even defining the tests that will validate that the software meets all requirements is impossible. It is also more cost-efficient first to get clarity on the requirements and then develop the software that meets them, then to first develop the software and get clarity along the way as that would most likely require rework because of gained insights. In addition, the requirements engineers will be more prone to discuss during or shortly after they document the requirements, then days, weeks, or even months after they complete the requirement definition and have moved on to the next assignment. This reduced cycle-time related to requirements definition supports business agility significantly.
I have written about the concept of TDD before, and you can read the first of three articles here:
In that series of three articles, I debunk the most common misconceptions around TDD and explain, through logic and experience, why TDD reduces the cost and time needed to deliver production-grade software.
Behavior-Driven Development
Behavior-driven development, or BDD, defines requirements in terms of a product’s features, how these features are expected to be used, and, consequently, how the software behaves in those scenarios.
This approach to defining requirements puts the focus on a product’s actual features and, therefore, its usefulness. Because BDD describes the intended or expected use of a feature in certain scenarios, it also addresses the features’ usability. BDD is, therefore, an excellent way to ensure that your product is both useful and usable.
Because APIs can be considered features of an application, BDD is very suitable for defining APIs and how they are expected to be used by an API consumer to accomplish specific tasks. By applying BDD practices and principles, an API’s usefulness and usability become clear even during the requirements definition phase, even before the API is defined, and most definitely before the API is implemented.
An additional benefit of BDD is that it can result in automated tests that validate the correct implementation of a feature when used in specific scenarios. Tools like Cucumber, covered in this article, will take the feature definition files written in Gherkin as input to run automated tests. When you define the features of your product as APIs, and you apply API-First principles (see the next section), then you will want to be able to mock your API implementations before implementing your API for real, thus testing your API’s usability and the opportunity to refine the API before spending all that time on its implementation.
I have written various articles on BDD, among them this one:
It explains the concept within the context of developing an API-only application.
Clap for this story when you like it thus far and are looking forward to read the update
API-First
API-first and API-only are two sides of the same coin. I have written this article on API-only:
That article explains how considering an application that exposes its features as APIs as an API-only application improves its usability. Within this context, API-first implies that something follows that is detrimental to the quality of the API.
An alternative way of thinking about API-First, which is also a more mature view of APIs, is to consider an API and its implementation as two sides of the same coin. One side is the API, which is the interface or contract, and the other is the interface’s implementation. Within this context, API-First means that first, you define the contract and the interface, and second, you develop the implementation that respects that contract.
Because API-first means that the API is defined independently and before its implementation, it also means that the API’s definition will not be biased towards a specific implementation. It will, therefore, be more based on how the API consumer will use the API, resulting in a more usable API.
Clap for this story when you like it thus far and are looking forward to read the update
The technologies
Applying WireMock, and Cucumber to develop Spring Boot applications
TDD, BDD, and API-First are concepts critical to the success of delivering useful and usable software. To enable you to develop useful and usable software by applying these three concepts, you will likely use WireMock, Cucumber, and Spring Boot. Unfortunately, these three tools, although very common in software engineering, don’t work together as a trio as seamlessly as one would expect.
The project is intended to demonstrate the use of WireMock in combination with Cucumber and Spring Boot.
These individual components will not be covered, as I will focus solely on integrating all three into a single application that exposes APIs.
As mentioned before, plenty of resources are available online explaining how to use the individual components, WireMock, or Cucumber in your Spring Boot application. At the time of this writing, though, I have not encountered a single online resource that explains how to use WireMock in your Spring Boot application during your BDD test using Cucumber. I tried several Gen AI tools to give me the information needed, but none of them could understand the intricacies of these three tools and why they don’t work together as one would expect or hope. This has motivated me to write this article, as it describes just that.
Source code
All source codes for this repository are available on GitHub under the MIT license.
Tooling
Besides WireMock, Cucumber, and Spring Boot, I have used Java 17, Amazon Corretto’s implementation, Gradle 8.12, and IntelliJ Idea CE. I will try to keep all dependencies, including tooling, as up-to-date as possible, ensuring that you will run the slightest risk possible of being impacted by vulnerabilities still, whenever you decide to clone the repository and run the application.
Update: This updated version of the article uses WireMock’s Spring Boot integration version 3.6.0. The original source code, based on version 3.5.1, is still available in the branch use_wiremock_pre_360
.
The project
The application in the aforementioned GitHub repository exposes two APIs. In fact, the application is in its very early stages and delivers two APIs that are as simple as “Hello World” but a bit more relevant. The APIs are described in the OpenAPI document openapi.json
located in the directory app/src/main/resources
. I am using the OpenAPI 3.1.1 specification.
Although I’m not using this OpenAPI description, it is relevant because the Cucumber feature files and the WireMock stubs are based on it. The example values defined in the OpenAPI description are especially relevant.
In my book “Software Engineering Done Right — the practice of delivering useful and usable software”, I cover API-First and how to apply it to developing applications that expose APIs. You can request access to the electronic version of the book through my Discord server:
WireMock and Spring Boot
WireMock has native support for Spring Boot, or maybe it is more accurate to say that it has native support for WireMock. Either way, a WireMock library is available that allows you to use WireMock in your Spring Boot applications to stub external APIs.
This library’s intention is to make you less dependent on APIs delivered by services that are not delivered by you. In microservice architecture, this could be microservices developed by other teams or possibly microservices that are not available in your development environment.
I wrote an article on ensuring your software is deployable, especially when developing microservices. When you must deal with unavailable microservices in your development environment, share this article with your colleagues and point out to them that they are costing your organization millions of €s because they either didn’t read the article or didn’t take it to heart.
By using WireMock, you can replace every API call to the external service with a WireMock stub, thus simulating the external service’s existence. Of course, you’ll need an accurate description of the external API for this to work.
̶W̶i̶r̶e̶M̶o̶c̶k̶ ̶i̶n̶t̶e̶g̶r̶a̶t̶i̶o̶n̶ ̶w̶i̶t̶h̶ ̶S̶p̶r̶i̶n̶g̶ ̶B̶o̶o̶t̶ ̶i̶s̶ ̶p̶r̶i̶m̶a̶r̶i̶l̶y̶ ̶i̶n̶t̶e̶n̶d̶e̶d̶ ̶t̶o̶ ̶t̶e̶s̶t̶ ̶y̶o̶u̶r̶ ̶a̶p̶p̶l̶i̶c̶a̶t̶i̶o̶n̶.̶ It is superb in that it provides programmatic access to WireMock, so you can configure it dynamically according to your application’s specific cases. For this purpose, I would not recommend using WireMock in a standalone configuration, for example, containerized or as a separate Java application, as that would be less flexible and harder to share in a shared environment like a UAT setup.
You can find the WireMock integration libraries for Spring Boot here: https://mvnrepository.com/artifact/org.wiremock.integrations.
Update: WireMock’s Spring Boot integration, with the release of version 3.6, allows the use of Gradle’s support of Cucumber-runners as a native jUnit test engine. This allows you to adopt Consumer Contract Driven Development as your way of API First development.
Cucumber and Spring Boot
Cucumber has native support for Spring Boot, or maybe it is more accurate to say that Spring Boot has native support for Cucumber. Either way, a Cucumber library is available that allows you to use Cucumber in your Spring Boot applications to test your Spring Boot application’s behavior as described in Cucumber feature files.
This library intends to use Cucumber as a jUnit Jupiter platform runner for SpringBootTest annotated tests. It will replace the standard jUnit runners with the Cucumber runner and give you access to the vast Cucumber ecosystem. This integration also injects the Spring Boot application context into your glue-code, making your steps more versatile.
The library will allow you to test the behavior of your Spring Boot application based on the Cucumber feature files. Like the WireMock integration library for Spring Boot, this library is also intended to test your Spring Boot application. Cucumber integration is also superb because it gives programmatic access to develop the most effective and efficient tests.
You can find the Cucumber integration libraries for Spring Boot here: https://mvnrepository.com/artifact/io.cucumber/cucumber-spring.
WireMock and Cucumber for API-First
As explained above, both tools have integration libraries for Spring Boot, which can be used to test your Spring Boot application. But what if you don’t yet have an application to test?
Clap for this story when you like it thus far and are looking forward to read the update.
This may sound like a silly question when you’re not using an API-First approach in developing APIs. But when you develop your products API-First, I don’t mean the misnomer for API-only. Still, the proper API-First approach is where you first describe a feature, next the API that provides access to the feature, and validate that it is useful and usable before implementing it. This ensures you’re not wasting your precious time on developing something nobody will ever want to use.
When you are applying API-First, you will want a way to ensure that the feature you defined using a Cucumber feature file, when exposed through an API described in an OpenAPI document, is useful and usable. For this purpose, WireMock is excellent, as it allows you to create mock implementations of APIs. It will enable you to define a stub for every API your application will expose, eventually, even before it is implemented. This way, you can consider the WireMock stub as the API’s first implementation, which comes at an extremely low cost.
You will still want to have a Spring Boot application, in its most basic incarnation, available because you will want to have some way to implement that application’s feature set gradually. You will want to incrementally add its APIs, iteratively, one API at a time. Because you will have WireMock stubs for all APIs not yet implemented, you can have a complete application available from day one that is fully functional without an API exposed by it and have it expose all APIs on the final day and in between one or more APIs are ‘implemented’ by WireMock stubs.
Therefore, the combination of WireMock and Cucumber is not intended to test your application but to validate the quality of your APIs in terms of usefulness and usability, even before they are implemented. Neither the WireMock integration libraries with Spring Boot nor the Cucumber integration libraries with Spring Boot cater to this intention.
Getting it all to work
I will not go into detail about what doesn’t work when you try to use the official ways to integrate WireMock and Spring Boot, Cucumber and WireMock, or all three together. I will also not explain why this is not working. In case you’re interested, there is a discussion in the WireMock GitHub project on using WireMock in Cucumber glue-code to test Spring Boot applications using the WireMock integration libraries and why it doesn’t work.
See https://github.com/wiremock/wiremock-spring-boot/discussions/22.
Update: The issue mentioned in discussion #22 has been formulated in issue #73, which has been addressed in PR #77. See https://github.com/wiremock/wiremock-spring-boot/issues/73
Project structure
The example project on GitHub with all the source code for this article focuses on how WireMock can be used to provide stubs for APIs tested using Cucumber. The intention was not to write picture-perfect source code, although I used common sense and did some refactoring once I got everything working to tidy up the code.
The approach demonstrated in this project will allow you to apply API-First by first defining your Cucumber feature files with the scenarios in which a feature is expected to be used.
Next, you can implement the relevant glue-code, using WireMock to provide the stubs for the API endpoints called by the application under test before they’re implemented for real. This will allow you to test your APIs and how they can be used to expose your application’s features before spending time implementing them.
I used Gradle’s feature to place all BDD tests in their directory, bdd-test
, which falls under app/src/
.
The WireMock configuration is also kept in its subdirectory, wiremock
, which falls directly under app/
. This allows WireMock stubs to be defined as separate JSON files instead of being implemented programmatically as part of the Cucumber steps. Because these files are not in the app/src/
subtree, they can be easily shared across file sets. It would allow the same stub definitions to be used for BDD, unit, and integration tests. Alternatively, I could have placed them in the resources
directory of the bdd-test
subdirectory, but that would have implied that the stubs are specific for the BDD tests, and that was not my intention.
Putting the stub definitions outside of the app/src/
subtree makes the stubs easier to maintain as they are explicitly independent of the glue-code. They can be defined and maintained by a different team and based on the OpenAPI description of the endpoint.
Clap for this story when you like it thus far and are looking forward to read the update
WireMock configuration
I have ensured WireMock is configured to run on a port different from the standard port 8080
because that is also the standard port for servlet containers like Apache Tomcat.
In the setup found on GitHub, you will find that I’ve already implemented one of the two APIs and, therefore, use WireMock’s proxy feature. This shows how to configure WireMock to gradually replace stubs with the actual implementations, facilitating true agile software delivery based on increments and iterations.
Update: WireMock 3.6.0 does support the annotations introduces with WireMock’s native support for Spring Boot while working with Cucumber. Meaning that you can use the @EnableWireMock annotation. I have deleted the text from the next paragraph, as it is no longer relevant.
̶T̶h̶e̶ ̶a̶n̶n̶o̶t̶a̶t̶i̶o̶n̶s̶ ̶i̶n̶t̶r̶o̶d̶u̶c̶e̶d̶ ̶b̶y̶ ̶W̶i̶r̶e̶M̶o̶c̶k̶’̶s̶ ̶n̶a̶t̶i̶v̶e̶ ̶s̶u̶p̶p̶o̶r̶t̶ ̶f̶o̶r̶ ̶S̶p̶r̶i̶n̶g̶ ̶B̶o̶o̶t̶ ̶w̶i̶l̶l̶ ̶w̶o̶r̶k̶ ̶w̶i̶t̶h̶ ̶C̶u̶c̶u̶m̶b̶e̶r̶,̶ ̶t̶h̶e̶ ̶d̶e̶p̶e̶n̶d̶e̶n̶c̶y̶ ̶o̶n̶ ̶W̶i̶r̶e̶M̶o̶c̶k̶ ̶i̶s̶ ̶s̶t̶i̶l̶l̶ ̶r̶e̶q̶u̶i̶r̶e̶d̶ ̶a̶n̶d̶ ̶s̶h̶o̶u̶l̶d̶,̶ ̶t̶h̶e̶r̶e̶f̶o̶r̶e̶,̶ ̶b̶e̶ ̶b̶a̶s̶e̶d̶ ̶o̶n̶ ̶t̶h̶e̶ ̶o̶r̶g̶.̶w̶i̶r̶e̶m̶o̶c̶k̶.̶i̶n̶t̶e̶g̶r̶a̶t̶i̶o̶n̶s̶:̶w̶i̶r̶e̶m̶o̶c̶k̶-̶s̶p̶r̶i̶n̶g̶-̶b̶o̶o̶t̶ ̶l̶i̶b̶r̶a̶r̶y̶ ̶i̶n̶s̶t̶e̶a̶d̶ ̶o̶f̶ ̶t̶h̶e̶ ̶r̶e̶g̶u̶l̶a̶r̶ ̶o̶r̶g̶.̶w̶i̶r̶e̶m̶o̶c̶k̶:̶w̶i̶r̶e̶m̶o̶c̶k̶ ̶l̶i̶b̶r̶a̶r̶y̶.̶ ̶
̶W̶i̶t̶h̶ ̶t̶h̶e̶ ̶l̶a̶t̶t̶e̶r̶,̶ ̶I̶ ̶h̶a̶d̶ ̶p̶r̶o̶b̶l̶e̶m̶s̶ ̶s̶h̶a̶r̶i̶n̶g̶ ̶W̶i̶r̶e̶M̶o̶c̶k̶ ̶d̶e̶f̶i̶n̶i̶t̶i̶o̶n̶s̶ ̶a̶c̶r̶o̶s̶s̶ ̶d̶i̶f̶f̶e̶r̶e̶n̶t̶ ̶c̶l̶a̶s̶s̶e̶s̶ ̶i̶n̶ ̶m̶y̶ ̶C̶u̶c̶u̶m̶b̶e̶r̶ ̶g̶l̶u̶e̶-̶c̶o̶d̶e̶.̶ ̶S̶w̶i̶t̶c̶h̶i̶n̶g̶ ̶t̶o̶ ̶t̶h̶e̶ ̶f̶o̶r̶m̶e̶r̶ ̶l̶i̶b̶r̶a̶r̶y̶ ̶s̶o̶l̶v̶e̶d̶ ̶a̶l̶l̶ ̶i̶s̶s̶u̶e̶s̶.̶ ̶T̶h̶i̶s̶ ̶w̶a̶s̶ ̶p̶r̶e̶t̶t̶y̶ ̶u̶n̶i̶n̶t̶u̶i̶t̶i̶v̶e̶ ̶s̶i̶n̶c̶e̶ ̶t̶h̶e̶ ̶W̶i̶r̶e̶M̶o̶c̶k̶ ̶S̶p̶r̶i̶n̶g̶ ̶B̶o̶o̶t̶ ̶i̶n̶t̶e̶g̶r̶a̶t̶i̶o̶n̶ ̶u̶s̶i̶n̶g̶ ̶t̶h̶e̶ ̶@̶I̶n̶j̶e̶c̶t̶W̶i̶r̶e̶M̶o̶c̶k̶ ̶a̶n̶n̶o̶t̶a̶t̶i̶o̶n̶,̶ ̶t̶h̶e̶ ̶a̶d̶v̶e̶r̶t̶i̶s̶e̶d̶ ̶w̶a̶y̶ ̶o̶f̶ ̶i̶n̶j̶e̶c̶t̶i̶n̶g̶ ̶W̶i̶r̶e̶M̶o̶c̶k̶ ̶o̶b̶j̶e̶c̶t̶s̶,̶ ̶d̶o̶e̶s̶n̶’̶t̶ ̶w̶o̶r̶k̶ ̶w̶i̶t̶h̶ ̶C̶u̶c̶u̶m̶b̶e̶r̶.̶ ̶O̶n̶e̶ ̶w̶o̶u̶l̶d̶ ̶t̶h̶i̶n̶k̶ ̶t̶h̶a̶t̶ ̶t̶h̶e̶ ̶S̶p̶r̶i̶n̶g̶ ̶B̶o̶o̶t̶ ̶i̶n̶t̶e̶g̶r̶a̶t̶i̶o̶n̶ ̶w̶o̶u̶l̶d̶ ̶n̶o̶t̶ ̶b̶e̶ ̶n̶e̶e̶d̶e̶d̶ ̶a̶n̶d̶ ̶t̶h̶e̶ ̶s̶t̶a̶n̶d̶a̶r̶d̶ ̶W̶i̶r̶e̶M̶o̶c̶k̶ ̶l̶i̶b̶r̶a̶r̶y̶ ̶w̶o̶u̶l̶d̶ ̶s̶u̶f̶f̶i̶c̶e̶,̶ ̶b̶u̶t̶ ̶t̶h̶a̶t̶ ̶w̶a̶s̶ ̶a̶ ̶w̶r̶o̶n̶g̶ ̶a̶s̶s̶u̶m̶p̶t̶i̶o̶n̶.̶
I’m using Gradle’s version catalog method of defining dependencies, which gives me more flexibility in managing dependency versions.
As mentioned, this application’s BDD part is in the app/src/bdd-test
directory, and the WireMock configuration is in the app/wiremock
directory.
The source code
This section has been replaced with references to the updated source code which uses WireMock’s support for Spring Boot with version 3.6.0 or later.
The WireMock server is no longer created in the WireMockConfig
class, which is removed from the project as it is no longer needed. Instead, the WireMock server is injected in the CucumberConfig
class by means of the @EnableWireMock annotation.
@Slf4j
@CucumberContextConfiguration
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = App.class)
@ActiveProfiles({"bddtest"})
@EnableWireMock(@ConfigureWireMock(registerSpringBean = true))
public class CucumberConfiguration {
}
Important: you must explicitly configure WireMock as a Spring Bean, otherwise the WireMock server will not be injected when using the Cucumber runner.
@EnableWireMock(@ConfigureWireMock(registerSpringBean = true))
There is no longer a need to create a WireMock server explicitly, the annotation is all you need for most cases. That is, while you’re using WireMock as your first implementation of the APIs you are still designing at this phase.
Keep the location of your stubs in the default locations and you’re golden. Configure WireMock as per the documentation when you feel like not using the convention.
In case you would like to configure WireMock as a proxy, you can do so, knowing that the WireMock server is configured and injected into your environment using the @EnableWireMock annotation I showed a few lines up.
@Given("the system is up and running")
public void theSystemIsUpAndRunning() {
stubFor(
get(urlMatching("/"))
.withHeader("Accept", WireMock.equalTo("application/json"))
.willReturn(aResponse().proxiedFrom(
testClient.getBaseUrl() + ":" + testClient.getPort()))
);
testClient.executeGet();
systemIsUpAndRunning = testClient.getStepData().getHttpStatus().is2xxSuccessful();
assertTrue(systemIsUpAndRunning);
}
Note that the code in the repository is commented out because the stub that is created is defined as a JSON file in the app/wiremock
directory.
{
"request": {
"method": "GET",
"url": "/",
"headers": {
"Accept": {
"equalTo": "application/json"
}
}
},
"response": {
"proxyBaseUrl": "http://localhost:9090"
}
}
Wrapping up
In this article, I explained the concepts TDD, BDD, and API-First and their significance in relation to developing useful and usable software. I also explained how WireMock and Cucumber integrate with the Spring Boot framework through dedicated libraries maintained by the WireMock and Cucumber communities. Both communities are very active, by the way.
I also explained how with version 3.6.0 the WireMock team added the capability of injecting the WireMock Server as a Spring Bean using the @EnableWireMocker annotation in combination with the Cucumber runner.
This is a significant improvement as it allows us to stay native and use WireMock, Cucumber, and Spring Boot together in a way the developers of these three technologies intended.
This allows for true API First development of APIs, using BDD to define the requirements of your product’s features, use WireMock as a first implementation of those features, leveraging the Spring Boot ecosystem, and finally use that same ecosystem to develop the actual implementations.
The article has a working example of such an application, which can be found here: https://github.com/Arc-E-Tect/sedr-wiremock-cucumber-experiment
If you want to learn more about the practice of delivering useful and usable software, become a member of my Discord server:
If you are interested in my book on this topic, please request access to the electronic version on Discord. All I want in return is your feedback on the book’s content, if you have any.
Clap for this story when you liked it and still have some claps available. You can give a story on Medium, any story, a max of 50 claps. It helps the author to get noticed for content you feel is note worthy.
Disclaimer
The text very explicitly communicates my own personal views, experiences, and practices. Any similarities with the views, experiences, and practices of any of my previous or current clients, customers, or employers are strictly coincidental. This post is, therefore, my own, and I am the sole author and copyright holder of it.
Credits
I want to give special thanks to my lovely wife, Olcay, who took the time and effort to review my article. I am confident that her feedback significantly improved the article’s quality.
Image credits: Created using Dall-E 3