diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java index ec768538fc8..ebdf48cd060 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java @@ -66,13 +66,13 @@ class DefaultWebTestClient implements WebTestClient { private final Duration timeout; - private final WebTestClient.Builder builder; + private final DefaultWebTestClientBuilder builder; private final AtomicLong requestIndex = new AtomicLong(); DefaultWebTestClient(WebClient.Builder clientBuilder, ClientHttpConnector connector, - @Nullable Duration timeout, WebTestClient.Builder webTestClientBuilder) { + @Nullable Duration timeout, DefaultWebTestClientBuilder webTestClientBuilder) { Assert.notNull(clientBuilder, "WebClient.Builder is required"); this.wiretapConnector = new WiretapConnector(connector); @@ -133,7 +133,7 @@ class DefaultWebTestClient implements WebTestClient { @Override public Builder mutate() { - return this.builder; + return new DefaultWebTestClientBuilder(this.builder); } @Override diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClientBuilder.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClientBuilder.java index e095d199178..309055fae34 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClientBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClientBuilder.java @@ -60,6 +60,11 @@ class DefaultWebTestClientBuilder implements WebTestClient.Builder { this(null, httpHandlerBuilder, null, null); } + DefaultWebTestClientBuilder(DefaultWebTestClientBuilder other) { + this(other.webClientBuilder.clone(), other.httpHandlerBuilder, other.connector, + other.responseTimeout); + } + DefaultWebTestClientBuilder(@Nullable WebClient.Builder webClientBuilder, @Nullable WebHttpHandlerBuilder httpHandlerBuilder, @Nullable ClientHttpConnector connector, @Nullable Duration responseTimeout) { @@ -150,12 +155,8 @@ class DefaultWebTestClientBuilder implements WebTestClient.Builder { connectorToUse = new HttpHandlerConnector(this.httpHandlerBuilder.build()); } - DefaultWebTestClientBuilder webTestClientBuilder = new DefaultWebTestClientBuilder( - this.webClientBuilder.clone(), this.httpHandlerBuilder, - this.connector, this.responseTimeout); - return new DefaultWebTestClient(this.webClientBuilder, - connectorToUse, this.responseTimeout, webTestClientBuilder); + connectorToUse, this.responseTimeout, new DefaultWebTestClientBuilder(this)); } } diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/MockServerIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/MockServerIntegrationTests.java index 4036ed9dbb2..dee84f01eec 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/MockServerIntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/MockServerIntegrationTests.java @@ -24,6 +24,7 @@ import org.springframework.http.ResponseCookie; import org.springframework.web.server.WebHandler; import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.Assert.*; /** * Mock server integration test scenarios. @@ -68,4 +69,39 @@ public class MockServerIntegrationTests { .expectBody(String.class).isEqualTo("bar"); } + @Test + public void mutateDoesCopy() throws Exception { + + WebTestClient.Builder builder = WebTestClient.bindToWebHandler(exchange -> exchange.getResponse().setComplete()).configureClient(); + builder.filter((request, next) -> next.exchange(request)); + builder.defaultHeader("foo", "bar"); + builder.defaultCookie("foo", "bar"); + WebTestClient client1 = builder.build(); + + builder.filter((request, next) -> next.exchange(request)); + builder.defaultHeader("baz", "qux"); + builder.defaultCookie("baz", "qux"); + WebTestClient client2 = builder.build(); + + WebTestClient.Builder mutatedBuilder = client1.mutate(); + + mutatedBuilder.filter((request, next) -> next.exchange(request)); + mutatedBuilder.defaultHeader("baz", "qux"); + mutatedBuilder.defaultCookie("baz", "qux"); + WebTestClient clientFromMutatedBuilder = mutatedBuilder.build(); + + client1.mutate().filters(filters -> assertEquals(1, filters.size())); + client1.mutate().defaultHeaders(headers -> assertEquals(1, headers.size())); + client1.mutate().defaultCookies(cookies -> assertEquals(1, cookies.size())); + + client2.mutate().filters(filters -> assertEquals(2, filters.size())); + client2.mutate().defaultHeaders(headers -> assertEquals(2, headers.size())); + client2.mutate().defaultCookies(cookies -> assertEquals(2, cookies.size())); + + clientFromMutatedBuilder.mutate().filters(filters -> assertEquals(2, filters.size())); + clientFromMutatedBuilder.mutate().defaultHeaders(headers -> assertEquals(2, headers.size())); + clientFromMutatedBuilder.mutate().defaultCookies(cookies -> assertEquals(2, cookies.size())); + } + + }