diff --git a/testing-modules/mockserver/pom.xml b/testing-modules/mockserver/pom.xml
index 3495ddb09d9d..896e5ced7b4b 100644
--- a/testing-modules/mockserver/pom.xml
+++ b/testing-modules/mockserver/pom.xml
@@ -15,6 +15,27 @@
+
+ org.springframework.boot
+ spring-boot-starter-web
+ ${spring-boot.version}
+
+
+ org.springframework
+ spring-webflux
+ ${spring.webflux.version}
+
+
+ org.springframework.boot
+ spring-boot-test
+ ${spring-boot.version}
+ test
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
org.mock-server
mockserver-netty
@@ -35,11 +56,33 @@
httpcore
${apche-http-version}
+
+ org.springframework.boot
+ spring-boot-test-autoconfigure
+ ${spring-boot.version}
+ test
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 17
+ 17
+
+
+
+
+
3.10.8
4.4.1
+ 3.3.2
+ 6.1.13
+ 2.18.0
\ No newline at end of file
diff --git a/testing-modules/mockserver/src/main/java/com/baeldung/mock/server/multiplerequests/Config.java b/testing-modules/mockserver/src/main/java/com/baeldung/mock/server/multiplerequests/Config.java
new file mode 100644
index 000000000000..72ae6f68a835
--- /dev/null
+++ b/testing-modules/mockserver/src/main/java/com/baeldung/mock/server/multiplerequests/Config.java
@@ -0,0 +1,15 @@
+package com.baeldung.mock.server.multiplerequests;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.reactive.function.client.WebClient;
+
+@Configuration
+public class Config {
+
+ @Bean
+ public WebClient webClient() {
+ return WebClient.create();
+ }
+
+}
diff --git a/testing-modules/mockserver/src/main/java/com/baeldung/mock/server/multiplerequests/PaymentController.java b/testing-modules/mockserver/src/main/java/com/baeldung/mock/server/multiplerequests/PaymentController.java
new file mode 100644
index 000000000000..463ba7d4b3cd
--- /dev/null
+++ b/testing-modules/mockserver/src/main/java/com/baeldung/mock/server/multiplerequests/PaymentController.java
@@ -0,0 +1,52 @@
+package com.baeldung.mock.server.multiplerequests;
+
+import java.util.UUID;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.client.WebClient;
+
+@RestController
+@RequestMapping("/api/")
+public class PaymentController {
+
+ private static final Logger logger = LoggerFactory.getLogger(PaymentController.class);
+ private final WebClient webClient;
+
+ public PaymentController(WebClient webClient) {
+ this.webClient = webClient;
+ }
+
+ @PostMapping("payment/process")
+ public ResponseEntity submitPayment(@RequestBody PaymentGatewayRequest paymentGatewayRequest) throws JSONException {
+
+ String paymentSubmissionResponse = webClient.post()
+ .uri("http://localhost:9090/payment/submit")
+ .body(BodyInserters.fromValue(paymentGatewayRequest))
+ .retrieve()
+ .bodyToMono(String.class)
+ .block();
+
+ UUID paymentId = UUID.fromString(new JSONObject(paymentSubmissionResponse).getString("paymentId"));
+ PaymentGatewayResponse.PaymentStatus paymentStatus = PaymentGatewayResponse.PaymentStatus.PENDING;
+ while (paymentStatus.equals(PaymentGatewayResponse.PaymentStatus.PENDING)) {
+ String paymentStatusResponse = webClient.get()
+ .uri("http://localhost:9090/payment/status/%s".formatted(paymentId))
+ .retrieve()
+ .bodyToMono(String.class)
+ .block();
+ paymentStatus = PaymentGatewayResponse.PaymentStatus.valueOf(new JSONObject(paymentStatusResponse).getString("paymentStatus"));
+ logger.info("Payment Status {}", paymentStatus);
+ }
+ return new ResponseEntity<>(new PaymentGatewayResponse(paymentId, paymentStatus), HttpStatus.OK);
+ }
+}
diff --git a/testing-modules/mockserver/src/main/java/com/baeldung/mock/server/multiplerequests/PaymentGatewayRequest.java b/testing-modules/mockserver/src/main/java/com/baeldung/mock/server/multiplerequests/PaymentGatewayRequest.java
new file mode 100644
index 000000000000..1fa1edc3a1ff
--- /dev/null
+++ b/testing-modules/mockserver/src/main/java/com/baeldung/mock/server/multiplerequests/PaymentGatewayRequest.java
@@ -0,0 +1,5 @@
+package com.baeldung.mock.server.multiplerequests;
+
+public record PaymentGatewayRequest(String cardNumber, String expiryMonth, String expiryYear, String currency, int amount, String cvv) {
+
+}
diff --git a/testing-modules/mockserver/src/main/java/com/baeldung/mock/server/multiplerequests/PaymentGatewayResponse.java b/testing-modules/mockserver/src/main/java/com/baeldung/mock/server/multiplerequests/PaymentGatewayResponse.java
new file mode 100644
index 000000000000..658cfb07cd33
--- /dev/null
+++ b/testing-modules/mockserver/src/main/java/com/baeldung/mock/server/multiplerequests/PaymentGatewayResponse.java
@@ -0,0 +1,16 @@
+package com.baeldung.mock.server.multiplerequests;
+
+import java.util.UUID;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public record PaymentGatewayResponse(UUID id, PaymentStatus status) {
+
+ public enum PaymentStatus {
+ PENDING,
+ AUTHORIZED,
+ DECLINED,
+ REJECTED
+ }
+}
diff --git a/testing-modules/mockserver/src/main/java/com/baeldung/mock/server/multiplerequests/SpringApplication.java b/testing-modules/mockserver/src/main/java/com/baeldung/mock/server/multiplerequests/SpringApplication.java
new file mode 100644
index 000000000000..b02dabf802d5
--- /dev/null
+++ b/testing-modules/mockserver/src/main/java/com/baeldung/mock/server/multiplerequests/SpringApplication.java
@@ -0,0 +1,12 @@
+package com.baeldung.mock.server.multiplerequests;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SpringApplication {
+
+ public static void main(String[] args) {
+ org.springframework.boot.SpringApplication.run(SpringApplication.class, args);
+ }
+
+}
diff --git a/testing-modules/mockserver/src/test/java/com/baeldung/mock/server/multiplerequests/PaymentControllerTest.java b/testing-modules/mockserver/src/test/java/com/baeldung/mock/server/multiplerequests/PaymentControllerTest.java
new file mode 100644
index 000000000000..9761cd6ca319
--- /dev/null
+++ b/testing-modules/mockserver/src/test/java/com/baeldung/mock/server/multiplerequests/PaymentControllerTest.java
@@ -0,0 +1,81 @@
+package com.baeldung.mock.server.multiplerequests;
+
+import static org.mockserver.integration.ClientAndServer.startClientAndServer;
+import static org.mockserver.model.HttpRequest.request;
+import static org.mockserver.model.HttpResponse.response;
+
+import java.util.UUID;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockserver.client.server.MockServerClient;
+import org.mockserver.integration.ClientAndServer;
+import org.mockserver.matchers.Times;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class PaymentControllerTest {
+
+ @Autowired
+ private WebTestClient webTestClient;
+
+ private ClientAndServer clientAndServer;
+
+ private final MockServerClient mockServerClient = new MockServerClient("localhost", 9090);
+
+ @BeforeEach
+ void setup() {
+ clientAndServer = startClientAndServer(9090);
+ }
+
+ @Test
+ void givenPaymentRequest_whenPaymentStatusChangesAfterFewSeconds_thenPaymentShouldBeProcessedSuccessfully() {
+
+ String paymentId = UUID.randomUUID()
+ .toString();
+ // When
+ mockServerClient.when(request().withMethod("POST")
+ .withPath("/payment/submit"))
+ .respond(response().withStatusCode(200)
+ .withBody("{\"paymentId\": \"%s\"}".formatted(paymentId))
+ .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE));
+
+ mockServerClient.when(request().withMethod("GET")
+ .withPath("/payment/status/%s".formatted(paymentId)), Times.exactly(4))
+ .respond(response().withStatusCode(200)
+ .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
+ .withBody("{\"paymentStatus\": \"%s\"}".formatted(PaymentGatewayResponse.PaymentStatus.PENDING.toString())));
+
+ mockServerClient.when(request().withMethod("GET")
+ .withPath("/payment/status/%s".formatted(paymentId)))
+ .respond(response().withStatusCode(200)
+ .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
+ .withBody("{\"paymentStatus\": \"%s\"}".formatted(PaymentGatewayResponse.PaymentStatus.AUTHORIZED.toString())));
+
+ webTestClient.post()
+ .uri("http://localhost:9000/api/payment/process")
+ .bodyValue(new PaymentGatewayRequest("4111111111111111", "12", "2025", "USD", 10000, "123"))
+ .exchange()
+ .expectStatus()
+ .isOk()
+ .expectBody(PaymentGatewayResponse.class)
+ .value(response -> {
+ Assertions.assertNotNull(response);
+ Assertions.assertEquals(PaymentGatewayResponse.PaymentStatus.AUTHORIZED, response.status());
+ });
+ }
+
+ @AfterEach
+ void tearDown() {
+ clientAndServer.stop();
+ }
+
+}
\ No newline at end of file