Getting Started with Component Testing with WireMock

Purushottam Sinha
3 min readOct 31, 2023

--

Photo by Laura Ockel on Unsplash

What is component testing?

The component test is a stage of the Test Pyramid which focuses on testing individual software components or modules in isolation from the rest of the system. It is a type of testing that focuses on verifying the functionality, performance, and reliability of each component separately to ensure that it meets its specified requirements.

Annotations

@SpringBootTest(classes = TestServiceApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@TestPropertySource(locations = {"classpath:application-test.yml", "classpath:bootstrap-test.yml"})
@Tag("integration")
@ActiveProfiles("test")
@WireMockTest
  1. SpringBootTest: It is used to launch the entire Spring Boot application context and test the application as a whole, including all the components and dependencies.
  2. TestPropertySource: It is used to specify the properties for a test class or method. It is used to override the default properties of the application or to provide additional properties for testing purposes.
  3. Tag (Optional): This is a optional property which can be used to separate running test in component test and JUnit test stages.
  4. ActiveProfiles: It is used to specify the active profiles for a test class or method. It is used to activate specific profiles for testing purposes so that we can modify the test configuration for different scenarios.
  5. WireMockTest: It is used to mock the HTTP responses from external services or APIs.

Steps for creating the Test Module

  1. Create the MyComponentTest.java file with the annotations as given below.
@SpringBootTest(classes = TestServiceApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@TestPropertySource(locations = {"classpath:application-test.yml", "classpath:bootstrap-test.yml"})
@Tag("integration")
@ActiveProfiles("test")
@WireMockTest
public class MyComponentTest {

}

2. Define a variable for WebClient for making call to your Application.

private WebClient webClient;

3. Define a mock Server using WireMock.

private WireMockServer testMockServer;

3. Initialize webClient and testMockServer and configure them in @BeforeEach.

@BeforeEach
public void setup() {
testMockServer = new WireMockServer(options().port(8444));
testMockServer.start();

webClient = WebClient.builder()
.baseUrl("http://localhost:" + port)
.defaultHeader(HttpHeaders.AUTHORIZATION, "Authorization Token")
.build();
}

4. Define a teardown function to cleanup the server configuration.

  @AfterEach
public void teardown() {
testMockServer.stop();
}

5. Write a test to check the end to end flow.

@Test
@DisplayName("Test through Rest API Call")
public void test_forCreateApprovalGroupRest() {
testMockServer.stubFor(post(urlEqualTo("/v1/getVal"))
.willReturn(aResponse()
.withStatus(200)
.withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.withBody("{\"message\":\"Hello, world!\"}")));

TestRequestPayload testRequest =
new TestRequestPayload(id, val);

Response res = webClient
.post()
.uri("/v1/test")
.body(Mono.just(testRequest), TestRequestPayload.class).retrieve().bodyToMono(
Response.class).block();

Assertions.assertNotNull(res);
}

Explanation:

A. For mocking the testMockServer,
- post(): Specify the method for the request
- urlEqualTo(): Give the endpoint of communication with the external server
- willReturn(): Specify the response
- aResponse(): It is a static method in the WireMock library that is used to create a mock HTTP response for testing purposes
- withStatus(): Define the statusCode for the response
- withHeader(): Add header for the response.
- withBody(): Body for the response

testMockServer.stubFor(post(urlEqualTo("/v1/getVal"))
.willReturn(aResponse()
.withStatus(200)
.withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.withBody("{\"message\":\"Hello, world!\"}")));

B. Use the webClient to make a API call to the Application, where /v1/test is one of the endpoints in the Controller.

Response res = webClient
.post()
.uri("/v1/test")
.body(Mono.just(testRequest), TestRequestPayload.class).retrieve().bodyToMono(
Response.class).block();

How to run the Component test

mvn clean test -Dgroups=integration -s settings.xml

--

--

No responses yet