Replace TestRestTemplate with RestTestClient in module tests

Before deprecating `TestRestTemplate`, we must first stop using it in
module tests and replace it with:
* `RestTestClient` when the Spring MVC infrastructure is present
* `RestClient` when the test does not have Spring MVC on classpath

See gh-46632
This commit is contained in:
Brian Clozel
2026-07-27 16:13:10 +02:00
parent 4daf90ada1
commit c06abc12ac
17 changed files with 255 additions and 236 deletions
@@ -25,10 +25,10 @@ import org.apache.hc.core5.util.TimeValue;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.boot.restclient.RestTemplateBuilder;
import org.springframework.boot.resttestclient.TestRestTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.test.web.servlet.client.RestTestClient;
import org.springframework.test.web.servlet.client.RestTestClient.BodySpec;
import org.springframework.test.web.servlet.client.StatusAssertions;
import static org.assertj.core.api.Assertions.assertThat;
@@ -40,23 +40,23 @@ import static org.assertj.core.api.Assertions.assertThat;
@SuppressWarnings("removal")
class DevToolsIntegrationTests extends AbstractDevToolsIntegrationTests {
private final TestRestTemplate template = new TestRestTemplate(new RestTemplateBuilder()
.requestFactory(() -> new HttpComponentsClientHttpRequestFactory(HttpClients.custom()
private final RestTestClient client = RestTestClient
.bindToServer(new HttpComponentsClientHttpRequestFactory(HttpClients.custom()
.setRetryStrategy(new DefaultHttpRequestRetryStrategy(10, TimeValue.of(1, TimeUnit.SECONDS)))
.build())));
.build()))
.build();
@ParameterizedTest(name = "{0}")
@MethodSource("parameters")
void addARequestMappingToAnExistingController(ApplicationLauncher applicationLauncher) throws Exception {
launchApplication(applicationLauncher, "--logging.level.org.springframework.boot=trace");
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
expectResponseBody(urlBase + "/one").isEqualTo("one");
expectResponseStatus(urlBase + "/two").isNotFound();
controller("com.example.ControllerOne").withRequestMapping("one").withRequestMapping("two").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForObject(urlBase + "/two", String.class)).isEqualTo("two");
expectResponseBody(urlBase + "/one").isEqualTo("one");
expectResponseBody(urlBase + "/two").isEqualTo("two");
}
@ParameterizedTest(name = "{0}")
@@ -64,11 +64,10 @@ class DevToolsIntegrationTests extends AbstractDevToolsIntegrationTests {
void removeARequestMappingFromAnExistingController(ApplicationLauncher applicationLauncher) throws Exception {
launchApplication(applicationLauncher);
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
expectResponseBody(urlBase + "/one").isEqualTo("one");
controller("com.example.ControllerOne").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForEntity(urlBase + "/one", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
expectResponseStatus(urlBase + "/one").isNotFound();
}
@ParameterizedTest(name = "{0}")
@@ -76,13 +75,12 @@ class DevToolsIntegrationTests extends AbstractDevToolsIntegrationTests {
void createAController(ApplicationLauncher applicationLauncher) throws Exception {
launchApplication(applicationLauncher);
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
expectResponseBody(urlBase + "/one").isEqualTo("one");
expectResponseStatus(urlBase + "/two").isNotFound();
controller("com.example.ControllerTwo").withRequestMapping("two").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForObject(urlBase + "/two", String.class)).isEqualTo("two");
expectResponseBody(urlBase + "/one").isEqualTo("one");
expectResponseBody(urlBase + "/two").isEqualTo("two");
}
@@ -91,16 +89,15 @@ class DevToolsIntegrationTests extends AbstractDevToolsIntegrationTests {
void createAControllerAndThenAddARequestMapping(ApplicationLauncher applicationLauncher) throws Exception {
launchApplication(applicationLauncher);
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
expectResponseBody(urlBase + "/one").isEqualTo("one");
expectResponseStatus(urlBase + "/two").isNotFound();
controller("com.example.ControllerTwo").withRequestMapping("two").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForObject(urlBase + "/two", String.class)).isEqualTo("two");
expectResponseBody(urlBase + "/one").isEqualTo("one");
expectResponseBody(urlBase + "/two").isEqualTo("two");
controller("com.example.ControllerTwo").withRequestMapping("two").withRequestMapping("three").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/three", String.class)).isEqualTo("three");
expectResponseBody(urlBase + "/three").isEqualTo("three");
}
@ParameterizedTest(name = "{0}")
@@ -109,18 +106,17 @@ class DevToolsIntegrationTests extends AbstractDevToolsIntegrationTests {
throws Exception {
launchApplication(applicationLauncher);
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
expectResponseBody(urlBase + "/one").isEqualTo("one");
expectResponseStatus(urlBase + "/two").isNotFound();
controller("com.example.ControllerTwo").withRequestMapping("two").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForObject(urlBase + "/two", String.class)).isEqualTo("two");
expectResponseBody(urlBase + "/one").isEqualTo("one");
expectResponseBody(urlBase + "/two").isEqualTo("two");
controller("com.example.ControllerOne").withRequestMapping("one").withRequestMapping("three").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForObject(urlBase + "/two", String.class)).isEqualTo("two");
assertThat(this.template.getForObject(urlBase + "/three", String.class)).isEqualTo("three");
expectResponseBody(urlBase + "/one").isEqualTo("one");
expectResponseBody(urlBase + "/two").isEqualTo("two");
expectResponseBody(urlBase + "/three").isEqualTo("three");
}
@ParameterizedTest(name = "{0}")
@@ -128,12 +124,11 @@ class DevToolsIntegrationTests extends AbstractDevToolsIntegrationTests {
void deleteAController(ApplicationLauncher applicationLauncher) throws Exception {
LaunchedApplication launchedApplication = launchApplication(applicationLauncher);
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
expectResponseBody(urlBase + "/one").isEqualTo("one");
assertThat(new File(launchedApplication.getClassesDirectory(), "com/example/ControllerOne.class").delete())
.isTrue();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForEntity(urlBase + "/one", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
expectResponseStatus(urlBase + "/one").isNotFound();
}
@@ -142,18 +137,16 @@ class DevToolsIntegrationTests extends AbstractDevToolsIntegrationTests {
void createAControllerAndThenDeleteIt(ApplicationLauncher applicationLauncher) throws Exception {
LaunchedApplication launchedApplication = launchApplication(applicationLauncher);
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
expectResponseBody(urlBase + "/one").isEqualTo("one");
expectResponseStatus(urlBase + "/two").isNotFound();
controller("com.example.ControllerTwo").withRequestMapping("two").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(this.template.getForObject(urlBase + "/two", String.class)).isEqualTo("two");
expectResponseBody(urlBase + "/one").isEqualTo("one");
expectResponseBody(urlBase + "/two").isEqualTo("two");
assertThat(new File(launchedApplication.getClassesDirectory(), "com/example/ControllerTwo.class").delete())
.isTrue();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(this.template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
expectResponseStatus(urlBase + "/two").isNotFound();
}
static Object[] parameters() {
@@ -163,4 +156,12 @@ class DevToolsIntegrationTests extends AbstractDevToolsIntegrationTests {
new Object[] { new JarFileRemoteApplicationLauncher(directories) } };
}
private BodySpec<String, ?> expectResponseBody(String url) {
return this.client.get().uri(url).exchangeSuccessfully().expectBody(String.class);
}
private StatusAssertions expectResponseStatus(String url) {
return this.client.get().uri(url).exchange().expectStatus();
}
}
@@ -19,10 +19,7 @@ package org.springframework.boot.devtools.tests;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.boot.resttestclient.TestRestTemplate;
import org.springframework.http.HttpStatus;
import static org.assertj.core.api.Assertions.assertThat;
import org.springframework.test.web.servlet.client.RestTestClient;
/**
* Integration tests for DevTools with lazy initialization enabled.
@@ -36,15 +33,14 @@ class DevToolsWithLazyInitializationIntegrationTests extends AbstractDevToolsInt
void addARequestMappingToAnExistingControllerWhenLazyInit(ApplicationLauncher applicationLauncher)
throws Exception {
launchApplication(applicationLauncher, "--spring.main.lazy-initialization=true");
TestRestTemplate template = new TestRestTemplate();
RestTestClient client = RestTestClient.bindToServer().build();
String urlBase = "http://localhost:" + awaitServerPort();
assertThat(template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(template.getForEntity(urlBase + "/two", String.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
client.get().uri(urlBase + "/one").exchangeSuccessfully().expectBody(String.class).isEqualTo("one");
client.get().uri(urlBase + "/two").exchange().expectStatus().isNotFound();
controller("com.example.ControllerOne").withRequestMapping("one").withRequestMapping("two").build();
urlBase = "http://localhost:" + awaitServerPort();
assertThat(template.getForObject(urlBase + "/one", String.class)).isEqualTo("one");
assertThat(template.getForObject(urlBase + "/two", String.class)).isEqualTo("two");
client.get().uri(urlBase + "/one").exchangeSuccessfully().expectBody(String.class).isEqualTo("one");
client.get().uri(urlBase + "/two").exchangeSuccessfully().expectBody(String.class).isEqualTo("two");
}
static Object[] parameters() {