API Acceptance Test Journey in Microservice Architecture using WireMock

Burcu Akkaya
5 min readJan 6, 2024

Hi everyone,

In this article, I’ll share our API Acceptance test experience as Seller Ads Team in Trendyol. As a team, we provide an interface where sellers can advertise. We are divided into 3 separate teams and prefer micro-architecture for service. By writing acceptance tests to micro-services, we make sure that each is in a healthy working order.

In a microservices architecture, services need to communicate with each other. If you are working on a project that implements a micro-service architect, there is no need for major challenges for API Testing. Mocking the APIs your service depends on solves many of the problems encountered when testing microservices. WireMock also enhances flexibility for API mocking. It’s the ability to create negative tests more easily, simulate edge cases, and generate faults in ways the API that’s why I chose this library to manage mock services.

In this article, I’ll share with you some tricks about parallel execution via the Wiremock features and also share a documentative project. Let’s get into the details of how to perform integration tests with mock API using WireMock starting from scratch!

Step 1: A Brief Overview of WireMock

WireMock is a free API mocking tool that can be run as a standalone server, or in a hosted version via the WireMock Cloud-managed service. It supports HTTP response stubbing, request verification, proxy/intercept, record/playback of stubs, and fault injection.

Stubbing and verifying features gives flexibility without affecting the live API. This isolation allows for more comprehensive testing, ensuring the app behaves correctly under different conditions.

Step 2: Set Up Your Project

First, You need to create a project depending on your chosen programming language and add the WireMock dependency to your project. If you’re using Maven, add the following to your pom.xml file:

<dependency>
<groupId>org.wiremock</groupId>
<artifactId>wiremock</artifactId>
<version>3.3.1</version>
</dependency>

The project not only used the WireMock dependency but also used Rest-Assured, etc. You can find an example pom.xml file at the end of the article.

Step 3: Create a WireMock Server

docker run -it --rm -p 8080:8080 --name  wiremock \
wiremock/wiremock:3.3.1 --verbose --https-port 2424 --enable-browser-proxying --trust-all-proxy-targets

Run this command on the project terminal. Then access http://localhost:8080/__admin/mappings to display the mapping sets.

An example mapping of the http://localhost:8080/__admin/mappings

As another solution, you can also stand the server by running docker-compose.yml to get rid of manual actions. Here is the example of the docker-compose.yml file:

docker-compose.yml

http://localhost:8089/__admin/webapp/mappings helps you to display the UI appearance for all mappings. You can create a server with saved hosts and ports and display the mapping set.

WireMock GUI

Step 4: Use the WireMock Server in Your Integration Tests

  • Create API Base Class and configure WireMock Server. The mock server must be configured before all test runs are started. All you need to set it up is to provide the host and port information. According to our project, the host is localhost, and the port is 8089.
  • Create Mock Controller Classes and enhance StubMappings for each endpoint. The WireMock stub-mapping functions used for each endpoint must be kept in a separate class in order to put forward a growth-appropriate and readable project.
  • Final step: Use mappings for your test cases. Create request-response examples and send WireMock for mappings. You can send a request via Rest-Assured functions and display the mapping result via http://localhost:8089/__admin/requests. The Wiremock will give a matching status and you can use that status and verify the test case via verify actions from The WireMock library.
A matched example of the success case

You can also configure stubs using JSON configuration files via .json file under the mapping directory. Let’s look at the example with the configuration.

Create a stub-mapping via JSON file and send the mapping to “locahost:8080/__admin/mappings” endpoint. The body of the response and header will be set with the created document.

  • Bonus Feature: Manage each mapping as suitable for parallel execution. Some cases can have the same URL that’s why we should separate each of the mappings. We’ve found 3 different methods to make unique mapping stubs.
  1. Defining a custom ID while creating a mapping allows you to distinguish your mappings. (specificStubMockId)
stubFor(post(WireMock.urlMatching("/users"))
.withId(specificStubMockId)
.withRequestBody(WireMock.equalToJson(requestBody))
.willReturn(
WireMock.aResponse()
.withStatus(statusCode)
.withHeader("Content-Type", "application/json; charset=UTF-8")
.withBody(responseBody))

2. Defining a Stub mapping with ThreadLocal while creating stub mapping allows us to store data that will be accessible only by a specific thread.

    private var stubPostUser: ThreadLocal<StubMapping>? = null

@BeforeMethod(alwaysRun = true)
fun beforeMethod() {
stubPostUser = ThreadLocal<StubMapping>()
}

@AfterMethod(alwaysRun = true)
fun afterMethod() {
if (stubPostUser?.get() != null)
removeStub(stubPostUser!!.get())
}

3. Defining an example of the request body while creating stub mapping allows us to distinguish your mappings.

stubFor(post(WireMock.urlMatching("/users"))
.withRequestBody(WireMock.equalToJson(requestBody))
.willReturn(
WireMock.aResponse()
.withStatus(statusCode)
.withHeader("Content-Type", "application/json; charset=UTF-8")
.withBody(responseBody))

Conclusion

Wiremock allows to you create edge cases and different fail scenarios which difficult to repeat. By creating integration tests with WireMock, you can ensure your application functions correctly and handle all possible scenarios. In this article, I tried to summarize the WireMock usage with Integration Testing and shared my own experience. You can find below an example project that you can easily adapt to your own scenarios.

References

We’re building a team of the brightest minds in our industry. Interested in joining us? Visit the pages below to learn more about our open positions.

--

--