Spring Boot Reactive Testing Part 2

This section we are going to discuss about how to test spring reactive client related areas. Assume this scenario we need to test integrate test for third party connectivity part.

Micro Service Architecture

Assume Above scenario we have to write unit test for Micro service A . Then Our first Article We have done how to write unit test for API level . This section covers how to write test cases for reactive client.

Assume Above Micro Service Contains Three Layers. First One Is API layer All the controllers . Second layer we have all the logic in service layer. And last part is Client Connection Layer . To Write Test for Client Connection Part Is the Hardest part in micro service.

WireMock

Why we need wiremock ? The simple answer is we need to assume third party responses & based on that write the test cases.

First need to Add WireMock Dependency to your project.

<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8</artifactId>
<version>2.27.2</version>
<scope>test</scope>
</dependency>

And next Add reactor-test dependency which will give utilities which will helps to write reactive assertions in your test class.

<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<version>3.1.0.RELEASE</version>
<scope>test</scope>
</dependency>

First Need to initialize WireMock Server for Third Party Connection. For That We have to add test configurations which will connect to localhost with different port. So that port we can start our own mock server. Then Each Request We can send response data which actually coming from third party API. In My Above Scenario I have added test configuration file to connect 7071 port.

Write Unit Test

Initialize WireMock Server In Unit Test

private WireMockServer wireMockServer;

@Autowired
ObjectMapper objectMapper;

@BeforeEach
void setUp() {
wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().port(7071));
wireMockServer.start();
}

@AfterEach
void tearDown() {
wireMockServer.stop();
}

Send Mock Data if client Send Request to mock Server.

wireMockServer.stubFor(get("/address/all")
.willReturn(okJson(jsonAsString)));

And Verify the Result.

Flux<Address> addressResponse = addressClient.getAllAddres();StepVerifier.create(addressResponse).expectNextCount(2).verifyComplete();

Full Code :

mport com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;

import java.util.ArrayList;
import java.util.List;

import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.okJson;

@SpringBootTest
@RunWith(SpringRunner.class)
@DirtiesContext
@AutoConfigureWebTestClient
public class MockClientTest {

private WireMockServer wireMockServer;

@Autowired
ObjectMapper objectMapper;

@BeforeEach
void setUp() {
wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().port(7071));
wireMockServer.start();
}

@AfterEach
void tearDown() {
wireMockServer.stop();
}

@Test
void testGetAddressList() throws JsonProcessingException {

List<Address> allLocations = new ArrayList<>();
allLocations.add(getMockAddress());
allLocations.add(getMockAddress());

String jsonInString = objectMapper.writeValueAsString(allLocations);

wireMockServer.stubFor(get("/address/all")
.willReturn(okJson(jsonInString)));

Flux<Address> addressResponse = addressClient.getAllAddres();
StepVerifier.create(addressResponse).expectNextCount(2).verifyComplete();

}
}

And these are the most used stub functions available in WireMock . Hope This Section Helps to write classes for reactive Web Client.

I write about Spring, Flutter, & AWS. Work with AWS Cloud strongly focusing on Security & Serverless