From 797e588d0d4b4f0cf99c8abd89fd56e016dad12a Mon Sep 17 00:00:00 2001 From: Thomas Recloux Date: Tue, 28 Oct 2025 12:29:40 +0100 Subject: [PATCH 1/2] fix: RestTestClient.mutate() should not have side effects Before this change, DefaultRestTestClient.mutate() was reusing the underlying builder all calls. Building a new builder for each call clones the RestTestClientBuilder, protecting from side effects. Signed-off-by: Thomas Recloux --- .../servlet/client/DefaultRestTestClient.java | 2 +- .../DefaultRestTestClientBuilderTests.java | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 spring-test/src/test/java/org/springframework/test/web/servlet/client/DefaultRestTestClientBuilderTests.java diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java index e95fb538f35..78de7d07d0c 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java @@ -132,7 +132,7 @@ private RequestBodyUriSpec methodInternal(HttpMethod httpMethod) { @SuppressWarnings("unchecked") @Override public > Builder mutate() { - return (Builder) this.restTestClientBuilder; + return new DefaultRestTestClientBuilder((DefaultRestTestClientBuilder) this.restTestClientBuilder); } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/client/DefaultRestTestClientBuilderTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/client/DefaultRestTestClientBuilderTests.java new file mode 100644 index 00000000000..ec32a834426 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/client/DefaultRestTestClientBuilderTests.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.web.servlet.client; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class DefaultRestTestClientBuilderTests { + + @Test + void testMutateHasNoSideEffects() { + RestTestClient baseTestClient = new DefaultRestTestClientBuilder().baseUrl("http://localhost").build(); + baseTestClient.mutate().defaultHeader("foo", "bar").build(); + baseTestClient.mutate().defaultHeaders(headers -> assertThat(headers.containsHeader("foo")).isFalse()); + } + +} From c72052c34e005bd6ae9be0e06e3be4102c73ca0f Mon Sep 17 00:00:00 2001 From: Thomas Recloux Date: Sat, 1 Nov 2025 16:11:04 +0100 Subject: [PATCH 2/2] move RestTestClientBuilder clone to mutate() Signed-off-by: Thomas Recloux --- .../test/web/servlet/client/DefaultRestTestClient.java | 2 +- .../test/web/servlet/client/DefaultRestTestClientBuilder.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java index 78de7d07d0c..83fb0a28ff4 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java @@ -132,7 +132,7 @@ private RequestBodyUriSpec methodInternal(HttpMethod httpMethod) { @SuppressWarnings("unchecked") @Override public > Builder mutate() { - return new DefaultRestTestClientBuilder((DefaultRestTestClientBuilder) this.restTestClientBuilder); + return new DefaultRestTestClientBuilder<>((DefaultRestTestClientBuilder) this.restTestClientBuilder); } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClientBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClientBuilder.java index 5957e345103..5d3f400d8bc 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClientBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClientBuilder.java @@ -166,7 +166,7 @@ public RestTestClient build() { } return new DefaultRestTestClient( - this.restClientBuilder, this.entityResultConsumer, new DefaultRestTestClientBuilder<>(this)); + this.restClientBuilder, this.entityResultConsumer, this); }