From f9b9b5975c638709cd91debc6de71245aa13dcf2 Mon Sep 17 00:00:00 2001 From: leohelfferich Date: Sat, 11 Oct 2025 11:18:29 +0200 Subject: [PATCH 1/5] fix imports to be able to compile --- .../src/main/java/com/baeldung/Application.java | 4 ++-- .../com/baeldung/mainclasstest/ApplicationArgumentsTest.java | 2 ++ .../java/com/baeldung/mainclasstest/ApplicationMainTest.java | 2 ++ .../java/com/baeldung/mainclasstest/ApplicationMockTest.java | 2 ++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/spring-boot-modules/spring-boot-testing-4/src/main/java/com/baeldung/Application.java b/spring-boot-modules/spring-boot-testing-4/src/main/java/com/baeldung/Application.java index 5f83b8f100db..eb089cbb7f17 100644 --- a/spring-boot-modules/spring-boot-testing-4/src/main/java/com/baeldung/Application.java +++ b/spring-boot-modules/spring-boot-testing-4/src/main/java/com/baeldung/Application.java @@ -1,4 +1,4 @@ -package com.baeldung.mainclasstest; +package com.baeldung; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -20,7 +20,7 @@ public static void main(String[] args) { initializeApplication(args); } - static ConfigurableApplicationContext initializeApplication(String[] args) { + public static ConfigurableApplicationContext initializeApplication(String[] args) { return SpringApplication.run(Application.class, args); } } \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationArgumentsTest.java b/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationArgumentsTest.java index 9985bb549010..f73764a78761 100644 --- a/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationArgumentsTest.java +++ b/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationArgumentsTest.java @@ -1,8 +1,10 @@ package com.baeldung.mainclasstest; import org.junit.jupiter.api.Test; +import com.baeldung.Application; public class ApplicationArgumentsTest { + @Test public void testMainWithArguments() { String[] args = { "--spring.profiles.active=test" }; diff --git a/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationMainTest.java b/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationMainTest.java index 43665c119f28..8ea559d6f9b6 100644 --- a/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationMainTest.java +++ b/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationMainTest.java @@ -2,6 +2,8 @@ import org.junit.jupiter.api.Test; +import com.baeldung.Application; + public class ApplicationMainTest { @Test diff --git a/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationMockTest.java b/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationMockTest.java index 8e57a91bb599..9d41e9c32472 100644 --- a/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationMockTest.java +++ b/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationMockTest.java @@ -6,6 +6,8 @@ import org.springframework.boot.SpringApplication; import org.springframework.context.ConfigurableApplicationContext; +import com.baeldung.Application; + public class ApplicationMockTest { @Test From 56b9cfc7959314f7e8c35ca27d5d5d9b4bf83dac Mon Sep 17 00:00:00 2001 From: leohelfferich Date: Sat, 11 Oct 2025 12:11:39 +0200 Subject: [PATCH 2/5] stash - does not work --- .../spring-boot-testing-4/pom.xml | 49 ++++++++++++++++++- .../resttestclient/RestTestClientTest.java | 27 ++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/resttestclient/RestTestClientTest.java diff --git a/spring-boot-modules/spring-boot-testing-4/pom.xml b/spring-boot-modules/spring-boot-testing-4/pom.xml index a1d239471e86..02a69b28a0c2 100644 --- a/spring-boot-modules/spring-boot-testing-4/pom.xml +++ b/spring-boot-modules/spring-boot-testing-4/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-testing-4 spring-boot-testing-4 @@ -14,6 +14,26 @@ 1.0.0-SNAPSHOT + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + + + + + + org.springframework + spring-framework-bom + 7.0.0-M9 + pom + import + + + + org.springframework.boot @@ -23,12 +43,37 @@ org.springframework.boot spring-boot-starter-test test + + + org.springframework + spring-core + + + org.springframework + spring-test + + + + + org.springframework + spring-core + test + + + org.springframework + spring-test + test org.mockito mockito-core test + + org.springframework + spring-web + test + diff --git a/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/resttestclient/RestTestClientTest.java b/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/resttestclient/RestTestClientTest.java new file mode 100644 index 000000000000..150ccaa7a690 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/resttestclient/RestTestClientTest.java @@ -0,0 +1,27 @@ +package com.baeldung.resttestclient; + +import org.junit.jupiter.api.Test; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.client.RestTestClient; + +public class RestTestClientTest { + + RestTestClient client = RestTestClient.bindToServer() + .baseUrl("http://localhost:8080") + .build(); + + @Test + void should() { + System.out.println("Foo"); + + client.get() + .uri("/persons/1") + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus() + .isOk() + .expectHeader() + .contentType(MediaType.APPLICATION_JSON); + } + +} From 4e4255e21211c0002fee4400be68619f8e5f44bd Mon Sep 17 00:00:00 2001 From: leohelfferich Date: Sun, 12 Oct 2025 12:22:51 +0200 Subject: [PATCH 3/5] override --- spring-boot-modules/spring-boot-4/pom.xml | 5 ++ .../resttestclient/RestTestClientTest.java | 3 +- .../spring-boot-testing-4/pom.xml | 49 +------------------ .../main/java/com/baeldung/Application.java | 4 +- .../ApplicationArgumentsTest.java | 2 - .../mainclasstest/ApplicationMainTest.java | 2 - .../mainclasstest/ApplicationMockTest.java | 2 - 7 files changed, 10 insertions(+), 57 deletions(-) rename spring-boot-modules/{spring-boot-testing-4/src/test/java/com/baeldung => spring-boot-4/src/test/java/com/baeldung/spring}/resttestclient/RestTestClientTest.java (93%) diff --git a/spring-boot-modules/spring-boot-4/pom.xml b/spring-boot-modules/spring-boot-4/pom.xml index 1fa59f2fb97e..2ca2a97240a9 100644 --- a/spring-boot-modules/spring-boot-4/pom.xml +++ b/spring-boot-modules/spring-boot-4/pom.xml @@ -42,6 +42,7 @@ org.projectlombok lombok true + provided org.mapstruct @@ -145,6 +146,10 @@ org.apache.maven.plugins maven-compiler-plugin + + 21 + 21 + diff --git a/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/resttestclient/RestTestClientTest.java b/spring-boot-modules/spring-boot-4/src/test/java/com/baeldung/spring/resttestclient/RestTestClientTest.java similarity index 93% rename from spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/resttestclient/RestTestClientTest.java rename to spring-boot-modules/spring-boot-4/src/test/java/com/baeldung/spring/resttestclient/RestTestClientTest.java index 150ccaa7a690..5e36a367875a 100644 --- a/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/resttestclient/RestTestClientTest.java +++ b/spring-boot-modules/spring-boot-4/src/test/java/com/baeldung/spring/resttestclient/RestTestClientTest.java @@ -1,4 +1,4 @@ -package com.baeldung.resttestclient; +package com.baeldung.spring.resttestclient; import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; @@ -23,5 +23,4 @@ void should() { .expectHeader() .contentType(MediaType.APPLICATION_JSON); } - } diff --git a/spring-boot-modules/spring-boot-testing-4/pom.xml b/spring-boot-modules/spring-boot-testing-4/pom.xml index 02a69b28a0c2..a1d239471e86 100644 --- a/spring-boot-modules/spring-boot-testing-4/pom.xml +++ b/spring-boot-modules/spring-boot-testing-4/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-testing-4 spring-boot-testing-4 @@ -14,26 +14,6 @@ 1.0.0-SNAPSHOT - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - - - - - - org.springframework - spring-framework-bom - 7.0.0-M9 - pom - import - - - - org.springframework.boot @@ -43,37 +23,12 @@ org.springframework.boot spring-boot-starter-test test - - - org.springframework - spring-core - - - org.springframework - spring-test - - - - - org.springframework - spring-core - test - - - org.springframework - spring-test - test org.mockito mockito-core test - - org.springframework - spring-web - test - diff --git a/spring-boot-modules/spring-boot-testing-4/src/main/java/com/baeldung/Application.java b/spring-boot-modules/spring-boot-testing-4/src/main/java/com/baeldung/Application.java index eb089cbb7f17..5f83b8f100db 100644 --- a/spring-boot-modules/spring-boot-testing-4/src/main/java/com/baeldung/Application.java +++ b/spring-boot-modules/spring-boot-testing-4/src/main/java/com/baeldung/Application.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.mainclasstest; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -20,7 +20,7 @@ public static void main(String[] args) { initializeApplication(args); } - public static ConfigurableApplicationContext initializeApplication(String[] args) { + static ConfigurableApplicationContext initializeApplication(String[] args) { return SpringApplication.run(Application.class, args); } } \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationArgumentsTest.java b/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationArgumentsTest.java index f73764a78761..9985bb549010 100644 --- a/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationArgumentsTest.java +++ b/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationArgumentsTest.java @@ -1,10 +1,8 @@ package com.baeldung.mainclasstest; import org.junit.jupiter.api.Test; -import com.baeldung.Application; public class ApplicationArgumentsTest { - @Test public void testMainWithArguments() { String[] args = { "--spring.profiles.active=test" }; diff --git a/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationMainTest.java b/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationMainTest.java index 8ea559d6f9b6..43665c119f28 100644 --- a/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationMainTest.java +++ b/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationMainTest.java @@ -2,8 +2,6 @@ import org.junit.jupiter.api.Test; -import com.baeldung.Application; - public class ApplicationMainTest { @Test diff --git a/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationMockTest.java b/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationMockTest.java index 9d41e9c32472..8e57a91bb599 100644 --- a/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationMockTest.java +++ b/spring-boot-modules/spring-boot-testing-4/src/test/java/com/baeldung/mainclasstest/ApplicationMockTest.java @@ -6,8 +6,6 @@ import org.springframework.boot.SpringApplication; import org.springframework.context.ConfigurableApplicationContext; -import com.baeldung.Application; - public class ApplicationMockTest { @Test From ad7c25e926a8d7e5711f1ef16a1f111b60965cbd Mon Sep 17 00:00:00 2001 From: leohelfferich Date: Sun, 2 Nov 2025 11:56:56 +0100 Subject: [PATCH 4/5] tests --- .../resttestclient/RestTestClientTest.java | 111 ++++++++++++++++-- 1 file changed, 103 insertions(+), 8 deletions(-) diff --git a/spring-boot-modules/spring-boot-4/src/test/java/com/baeldung/spring/resttestclient/RestTestClientTest.java b/spring-boot-modules/spring-boot-4/src/test/java/com/baeldung/spring/resttestclient/RestTestClientTest.java index 5e36a367875a..f8fd5f87a969 100644 --- a/spring-boot-modules/spring-boot-4/src/test/java/com/baeldung/spring/resttestclient/RestTestClientTest.java +++ b/spring-boot-modules/spring-boot-4/src/test/java/com/baeldung/spring/resttestclient/RestTestClientTest.java @@ -1,26 +1,121 @@ package com.baeldung.spring.resttestclient; +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.test.web.servlet.client.RestTestClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.WebApplicationContext; +@SpringBootTest public class RestTestClientTest { - RestTestClient client = RestTestClient.bindToServer() - .baseUrl("http://localhost:8080") - .build(); + @Autowired + private MyController myController; + + private RestTestClient restTestClient; + + @BeforeEach + void beforeEach(WebApplicationContext context) { + var restTestClientBuilder = RestTestClient.bindToController(myController); + restTestClient = restTestClientBuilder + //.baseUrl("/public") // 1) + //.defaultHeader("ContentType", "application/json") // 2) + //.defaultCookie("JSESSIONID", "abc123def456ghi789") // 3) + .build(); + + } @Test - void should() { - System.out.println("Foo"); + void givenValidPath_WhenCalled_ThenReturnOk() { + restTestClient.get() + .uri("/persons/1") + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus() + .isOk() + .expectBody(Person.class) + .isEqualTo(new Person(1L, "John Doe")); + } - client.get() + @Test + void givenWrongCallType_WhenCalled_ThenReturnClientError() { + restTestClient.post() // <=== wrong type + .uri("/persons/1") + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus() + .is4xxClientError(); + } + + @Test + void givenWrongId_WhenCalled_ThenReturnNoContent() { + restTestClient.get() + .uri("/persons/0") // <=== wrong id + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus() + .isNoContent(); + } + + @Test + void givenInvalidPath_WhenCalled_ThenReturnNotFound() { + restTestClient.get() + .uri("/invalid") + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus() + .isNotFound(); + } + + @Test + void givenValidId_whenGetPerson_thenReturnsCorrectFields() { + restTestClient.get() + .uri("/persons/1") + .exchange() + .expectStatus() + .isOk() + .expectBody() + .jsonPath("$.id") + .isEqualTo(1) + .jsonPath("$.name") + .isEqualTo("John Doe"); + } + + @Test + void givenValidRequest_whenGetPerson_thenPassesAllAssertions() { + restTestClient.get() .uri("/persons/1") .accept(MediaType.APPLICATION_JSON) .exchange() .expectStatus() .isOk() - .expectHeader() - .contentType(MediaType.APPLICATION_JSON); + .expectBody(Person.class) + .consumeWith(result -> { + assertThat(result.getStatus().value()).isEqualTo(200); + assertThat(result.getResponseBody().name()).isEqualTo("John Doe"); + }); } } + +@RestController("my") +class MyController { + + @GetMapping("/persons/{id}") + public ResponseEntity getPersonById(@PathVariable Long id) { + return id == 1 ? ResponseEntity.ok(new Person(1L, "John Doe")) : ResponseEntity.noContent() + .build(); + } +} + +record Person(Long id, String name) { + +} From 4de1423fb510addaa21643ea8f8a52ac72bca3f5 Mon Sep 17 00:00:00 2001 From: leohelfferich Date: Sun, 2 Nov 2025 16:31:56 +0100 Subject: [PATCH 5/5] done --- spring-boot-modules/spring-boot-4/pom.xml | 4 ++ .../resttestclient/RestTestClientTest.java | 67 ++++++++++++++++--- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/spring-boot-modules/spring-boot-4/pom.xml b/spring-boot-modules/spring-boot-4/pom.xml index 2ca2a97240a9..4e2b475d3b2c 100644 --- a/spring-boot-modules/spring-boot-4/pom.xml +++ b/spring-boot-modules/spring-boot-4/pom.xml @@ -63,6 +63,10 @@ spring-boot-starter-test test + + org.springframework.boot + spring-boot-starter-webflux + diff --git a/spring-boot-modules/spring-boot-4/src/test/java/com/baeldung/spring/resttestclient/RestTestClientTest.java b/spring-boot-modules/spring-boot-4/src/test/java/com/baeldung/spring/resttestclient/RestTestClientTest.java index f8fd5f87a969..991e79d02401 100644 --- a/spring-boot-modules/spring-boot-4/src/test/java/com/baeldung/spring/resttestclient/RestTestClientTest.java +++ b/spring-boot-modules/spring-boot-4/src/test/java/com/baeldung/spring/resttestclient/RestTestClientTest.java @@ -2,11 +2,13 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.util.List; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.HttpHeaders; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.test.web.servlet.client.RestTestClient; @@ -15,23 +17,25 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.WebApplicationContext; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + @SpringBootTest public class RestTestClientTest { @Autowired private MyController myController; + @Autowired + private AnotherController anotherController; + + @Autowired private RestTestClient restTestClient; @BeforeEach void beforeEach(WebApplicationContext context) { - var restTestClientBuilder = RestTestClient.bindToController(myController); - restTestClient = restTestClientBuilder - //.baseUrl("/public") // 1) - //.defaultHeader("ContentType", "application/json") // 2) - //.defaultCookie("JSESSIONID", "abc123def456ghi789") // 3) + restTestClient = RestTestClient.bindToController(myController, anotherController) .build(); - } @Test @@ -100,10 +104,35 @@ void givenValidRequest_whenGetPerson_thenPassesAllAssertions() { .isOk() .expectBody(Person.class) .consumeWith(result -> { - assertThat(result.getStatus().value()).isEqualTo(200); - assertThat(result.getResponseBody().name()).isEqualTo("John Doe"); + assertThat(result.getStatus() + .value()).isEqualTo(200); + assertThat(result.getResponseBody() + .name()).isEqualTo("John Doe"); }); } + + @Test + void givenValidQuery_whenGetPersonsStream_thenReturnsFlux() { + restTestClient.get() + .uri("/persons") + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus() + .isOk() + .expectBody(new ParameterizedTypeReference>() {}); + } + + @Test + void givenValidQueryToSecondController_whenGetPenguinMono_thenReturnsEmpty() { + restTestClient.get() + .uri("/pink/penguin") + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus() + .isOk() + .expectBody(Penguin.class) + .value(it -> assertThat(it).isNull()); + } } @RestController("my") @@ -114,8 +143,26 @@ public ResponseEntity getPersonById(@PathVariable Long id) { return id == 1 ? ResponseEntity.ok(new Person(1L, "John Doe")) : ResponseEntity.noContent() .build(); } + + @GetMapping("/persons") + public Flux getAllPersons() { + var persons = List.of( + new Person(1L, "John Doe"), + new Person(2L, "James Bond"), + new Person(3L, "Alice In Wonderland") + ); + return Flux.fromIterable(persons); + } } -record Person(Long id, String name) { +@RestController("my2") +class AnotherController { + @GetMapping("/pink/penguin") + public Mono getPinkPenguin() { + return Mono.empty(); + } } + +record Person(Long id, String name) { } +record Penguin(Long id) { }