Browse Source

MockMvcHttpConnector supports RequestPostProcessor's

Closes gh-31298
pull/31316/head
rstoyanchev 1 year ago
parent
commit
af7fe013b6
  1. 10
      spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClientBuilder.java
  2. 12
      spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java
  3. 20
      spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcHttpConnector.java
  4. 82
      spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/FrameworkExtensionTests.java
  5. 15
      spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/FrameworkExtensionTests.java

10
spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClientBuilder.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 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.
@ -80,7 +80,7 @@ class DefaultWebTestClientBuilder implements WebTestClient.Builder { @@ -80,7 +80,7 @@ class DefaultWebTestClientBuilder implements WebTestClient.Builder {
private final WebHttpHandlerBuilder httpHandlerBuilder;
@Nullable
private final ClientHttpConnector connector;
private ClientHttpConnector connector;
@Nullable
private String baseUrl;
@ -277,6 +277,12 @@ class DefaultWebTestClientBuilder implements WebTestClient.Builder { @@ -277,6 +277,12 @@ class DefaultWebTestClientBuilder implements WebTestClient.Builder {
return this;
}
@Override
public WebTestClient.Builder clientConnector(ClientHttpConnector connector) {
this.connector = connector;
return this;
}
@Override
public WebTestClient build() {
ClientHttpConnector connectorToUse = this.connector;

12
spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java

@ -512,6 +512,18 @@ public interface WebTestClient { @@ -512,6 +512,18 @@ public interface WebTestClient {
*/
Builder responseTimeout(Duration timeout);
/**
* Set the {@link ClientHttpConnector} to use.
* <p>By default, this is initialized and set internally. However, the
* connector may also be prepared externally and passed via
* {@link WebTestClient#bindToServer(ClientHttpConnector)} such as for
* {@code MockMvcWebTestClient} tests, and in that case you can use this
* from {@link #mutateWith(WebTestClientConfigurer)} to replace it.
* @param connector the connector to use
* @since 6.1
*/
Builder clientConnector(ClientHttpConnector connector);
/**
* Apply the given configurer to this builder instance.
* <p>This can be useful for applying pre-packaged customizations.

20
spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcHttpConnector.java

@ -19,6 +19,7 @@ package org.springframework.test.web.servlet.client; @@ -19,6 +19,7 @@ package org.springframework.test.web.servlet.client;
import java.io.StringWriter;
import java.net.URI;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
@ -56,6 +57,7 @@ import org.springframework.test.web.servlet.RequestBuilder; @@ -56,6 +57,7 @@ import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@ -82,9 +84,16 @@ public class MockMvcHttpConnector implements ClientHttpConnector { @@ -82,9 +84,16 @@ public class MockMvcHttpConnector implements ClientHttpConnector {
private final MockMvc mockMvc;
private final List<RequestPostProcessor> requestPostProcessors;
public MockMvcHttpConnector(MockMvc mockMvc) {
this(mockMvc, Collections.emptyList());
}
private MockMvcHttpConnector(MockMvc mockMvc, List<RequestPostProcessor> requestPostProcessors) {
this.mockMvc = mockMvc;
this.requestPostProcessors = new ArrayList<>(requestPostProcessors);
}
@ -135,6 +144,8 @@ public class MockMvcHttpConnector implements ClientHttpConnector { @@ -135,6 +144,8 @@ public class MockMvcHttpConnector implements ClientHttpConnector {
}
}
this.requestPostProcessors.forEach(requestBuilder::with);
return requestBuilder;
}
@ -207,6 +218,15 @@ public class MockMvcHttpConnector implements ClientHttpConnector { @@ -207,6 +218,15 @@ public class MockMvcHttpConnector implements ClientHttpConnector {
return clientResponse;
}
/**
* Create a new instance that applies the given {@link RequestPostProcessor}s
* to performed requests.
* @since 6.1
*/
public MockMvcHttpConnector with(List<RequestPostProcessor> postProcessors) {
return new MockMvcHttpConnector(this.mockMvc, postProcessors);
}
private static class MockMvcServerClientHttpResponse
extends MockClientHttpResponse implements MockServerClientHttpResponse {

82
spring-test/src/test/java/org/springframework/test/web/servlet/samples/client/standalone/FrameworkExtensionTests.java

@ -17,11 +17,17 @@ @@ -17,11 +17,17 @@
package org.springframework.test.web.servlet.samples.client.standalone;
import java.security.Principal;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpHeaders;
import org.springframework.http.client.reactive.ClientHttpConnector;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.test.web.reactive.server.WebTestClientConfigurer;
import org.springframework.test.web.servlet.client.MockMvcHttpConnector;
import org.springframework.test.web.servlet.client.MockMvcWebTestClient;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
import org.springframework.test.web.servlet.setup.ConfigurableMockMvcBuilder;
@ -30,6 +36,7 @@ import org.springframework.util.Assert; @@ -30,6 +36,7 @@ import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
import static org.mockito.Mockito.mock;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -50,16 +57,16 @@ public class FrameworkExtensionTests { @@ -50,16 +57,16 @@ public class FrameworkExtensionTests {
@Test
public void fooHeader() {
this.client.get().uri("/")
.header("Foo", "a=b")
this.client.mutateWith(headers().foo("a=b"))
.get().uri("/")
.exchange()
.expectBody(String.class).isEqualTo("Foo");
}
@Test
public void barHeader() {
this.client.get().uri("/")
.header("Bar", "a=b")
this.client.mutateWith(headers().bar("a=b"))
.get().uri("/")
.exchange()
.expectBody(String.class).isEqualTo("Bar");
}
@ -68,6 +75,68 @@ public class FrameworkExtensionTests { @@ -68,6 +75,68 @@ public class FrameworkExtensionTests {
return new TestMockMvcConfigurer();
}
private static TestWebTestClientConfigurer headers() {
return new TestWebTestClientConfigurer();
}
/**
* Test WebTestClientConfigurer that re-creates the MockMvcHttpConnector
* with a {@code TestRequestPostProcessor}.
*/
private static class TestWebTestClientConfigurer implements WebTestClientConfigurer {
private final TestRequestPostProcessor requestPostProcessor = new TestRequestPostProcessor();
public TestWebTestClientConfigurer foo(String value) {
this.requestPostProcessor.foo(value);
return this;
}
public TestWebTestClientConfigurer bar(String value) {
this.requestPostProcessor.bar(value);
return this;
}
@Override
public void afterConfigurerAdded(
WebTestClient.Builder builder, WebHttpHandlerBuilder httpHandlerBuilder,
ClientHttpConnector connector) {
if (connector instanceof MockMvcHttpConnector mockMvcConnector) {
builder.clientConnector(mockMvcConnector.with(List.of(this.requestPostProcessor)));
}
}
}
/**
* Test {@code RequestPostProcessor} for custom headers.
*/
private static class TestRequestPostProcessor implements RequestPostProcessor {
private final HttpHeaders headers = new HttpHeaders();
public TestRequestPostProcessor foo(String value) {
this.headers.add("Foo", value);
return this;
}
public TestRequestPostProcessor bar(String value) {
this.headers.add("Bar", value);
return this;
}
@Override
public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) {
for (String headerName : this.headers.keySet()) {
request.addHeader(headerName, this.headers.get(headerName));
}
return request;
}
}
/**
* Test {@code MockMvcConfigurer}.
@ -80,8 +149,9 @@ public class FrameworkExtensionTests { @@ -80,8 +149,9 @@ public class FrameworkExtensionTests {
}
@Override
public RequestPostProcessor beforeMockMvcCreated(ConfigurableMockMvcBuilder<?> builder,
WebApplicationContext context) {
public RequestPostProcessor beforeMockMvcCreated(
ConfigurableMockMvcBuilder<?> builder, WebApplicationContext context) {
return request -> {
request.setUserPrincipal(mock());
return request;

15
spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/FrameworkExtensionTests.java

@ -18,7 +18,6 @@ package org.springframework.test.web.servlet.samples.standalone; @@ -18,7 +18,6 @@ package org.springframework.test.web.servlet.samples.standalone;
import java.security.Principal;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpHeaders;
@ -53,14 +52,9 @@ import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standal @@ -53,14 +52,9 @@ import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standal
*/
public class FrameworkExtensionTests {
private MockMvc mockMvc;
private final MockMvc mockMvc = standaloneSetup(new SampleController()).apply(defaultSetup()).build();
@BeforeEach
public void setup() {
this.mockMvc = standaloneSetup(new SampleController()).apply(defaultSetup()).build();
}
@Test
public void fooHeader() throws Exception {
this.mockMvc.perform(get("/").with(headers().foo("a=b"))).andExpect(content().string("Foo"));
@ -81,7 +75,7 @@ public class FrameworkExtensionTests { @@ -81,7 +75,7 @@ public class FrameworkExtensionTests {
/**
* Test {@code RequestPostProcessor}.
* Test {@code RequestPostProcessor} for custom headers.
*/
private static class TestRequestPostProcessor implements RequestPostProcessor {
@ -119,8 +113,9 @@ public class FrameworkExtensionTests { @@ -119,8 +113,9 @@ public class FrameworkExtensionTests {
}
@Override
public RequestPostProcessor beforeMockMvcCreated(ConfigurableMockMvcBuilder<?> builder,
WebApplicationContext context) {
public RequestPostProcessor beforeMockMvcCreated(
ConfigurableMockMvcBuilder<?> builder, WebApplicationContext context) {
return request -> {
request.setUserPrincipal(mock());
return request;

Loading…
Cancel
Save