diff --git a/config/checkstyle/import-control.xml b/config/checkstyle/import-control.xml index 1674da76c3e..2d591aaaa22 100644 --- a/config/checkstyle/import-control.xml +++ b/config/checkstyle/import-control.xml @@ -109,6 +109,10 @@ + + + + diff --git a/module/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientBuilderCustomizer.java b/core/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/client/WebTestClientBuilderCustomizer.java similarity index 79% rename from module/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientBuilderCustomizer.java rename to core/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/client/WebTestClientBuilderCustomizer.java index a3f911a3bb2..7cd12f2da2b 100644 --- a/module/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientBuilderCustomizer.java +++ b/core/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/client/WebTestClientBuilderCustomizer.java @@ -14,14 +14,17 @@ * limitations under the License. */ -package org.springframework.boot.web.server.test.client.reactive; +package org.springframework.boot.test.web.reactive.client; +import org.springframework.context.ApplicationContext; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient.Builder; /** * A customizer that can be implemented by beans wishing to customize the {@link Builder} - * to fine-tine its auto-configuration before a {@link WebTestClient} is created. + * to fine-tune its auto-configuration before a {@link WebTestClient} is created. + * Implementations can be registered in the {@link ApplicationContext} or + * {@code spring.factories}. * * @author Andy Wilkinson * @since 4.0.0 diff --git a/module/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizer.java b/core/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizer.java similarity index 56% rename from module/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizer.java rename to core/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizer.java index cb342f31a37..d6729722357 100644 --- a/module/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizer.java +++ b/core/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizer.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.web.server.test.client.reactive; +package org.springframework.boot.test.web.reactive.client; -import java.util.Collection; +import java.util.ArrayList; +import java.util.List; -import jakarta.servlet.ServletContext; import org.jspecify.annotations.Nullable; import org.springframework.aot.AotDetector; @@ -28,31 +28,26 @@ import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.http.codec.CodecCustomizer; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.reactive.AbstractReactiveWebServerFactory; +import org.springframework.boot.test.http.server.BaseUrl; +import org.springframework.boot.test.http.server.BaseUrlProviders; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.ConfigurationClassPostProcessor; import org.springframework.core.Ordered; +import org.springframework.core.io.support.SpringFactoriesLoader; +import org.springframework.core.io.support.SpringFactoriesLoader.ArgumentResolver; import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.MergedContextConfiguration; import org.springframework.test.context.TestContextAnnotationUtils; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.reactive.function.client.ExchangeStrategies; /** * {@link ContextCustomizer} for {@link WebTestClient}. @@ -61,13 +56,6 @@ import org.springframework.web.reactive.function.client.ExchangeStrategies; */ class WebTestClientContextCustomizer implements ContextCustomizer { - private static final boolean codecCustomizerPresent; - - static { - ClassLoader loader = WebTestClientContextCustomizerFactory.class.getClassLoader(); - codecCustomizerPresent = ClassUtils.isPresent("org.springframework.boot.http.codec.CodecCustomizer", loader); - } - @Override public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) { if (AotDetector.useGeneratedArtifacts()) { @@ -111,8 +99,7 @@ class WebTestClientContextCustomizer implements ContextCustomizer { */ static class WebTestClientRegistrar implements BeanDefinitionRegistryPostProcessor, Ordered, BeanFactoryAware { - @SuppressWarnings("NullAway.Init") - private BeanFactory beanFactory; + private @Nullable BeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { @@ -126,7 +113,7 @@ class WebTestClientContextCustomizer implements ContextCustomizer { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { - if (AotDetector.useGeneratedArtifacts()) { + if (this.beanFactory == null || AotDetector.useGeneratedArtifacts()) { return; } if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors((ListableBeanFactory) this.beanFactory, @@ -134,7 +121,6 @@ class WebTestClientContextCustomizer implements ContextCustomizer { registry.registerBeanDefinition(WebTestClient.class.getName(), new RootBeanDefinition(WebTestClientFactory.class)); } - } @Override @@ -148,15 +134,10 @@ class WebTestClientContextCustomizer implements ContextCustomizer { */ public static class WebTestClientFactory implements FactoryBean, ApplicationContextAware { - @SuppressWarnings("NullAway.Init") - private ApplicationContext applicationContext; + private @Nullable ApplicationContext applicationContext; private @Nullable WebTestClient object; - private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext"; - - private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.context.reactive.ReactiveWebApplicationContext"; - @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; @@ -181,87 +162,29 @@ class WebTestClientContextCustomizer implements ContextCustomizer { } private WebTestClient createWebTestClient() { - boolean sslEnabled = isSslEnabled(this.applicationContext); - String port = this.applicationContext.getEnvironment().getProperty("local.server.port", "8080"); - String baseUrl = getBaseUrl(sslEnabled, port); + Assert.state(this.applicationContext != null, "ApplicationContext not injected"); WebTestClient.Builder builder = WebTestClient.bindToServer(); customizeWebTestClientBuilder(builder, this.applicationContext); - if (codecCustomizerPresent) { - WebTestClientCodecCustomizer.customizeWebTestClientCodecs(builder, this.applicationContext); - } - return builder.baseUrl(baseUrl).build(); - } - - private String getBaseUrl(boolean sslEnabled, String port) { - String basePath = deduceBasePath(); - String pathSegment = (StringUtils.hasText(basePath)) ? basePath : ""; - return (sslEnabled ? "https" : "http") + "://localhost:" + port + pathSegment; - } - - private @Nullable String deduceBasePath() { - WebApplicationType webApplicationType = deduceFromApplicationContext(this.applicationContext.getClass()); - if (webApplicationType == WebApplicationType.REACTIVE) { - return this.applicationContext.getEnvironment().getProperty("spring.webflux.base-path"); - } - else if (webApplicationType == WebApplicationType.SERVLET) { - ServletContext servletContext = ((WebApplicationContext) this.applicationContext).getServletContext(); - Assert.state(servletContext != null, "'servletContext' must not be null"); - return servletContext.getContextPath(); - } - return null; - } - - static WebApplicationType deduceFromApplicationContext(Class applicationContextClass) { - if (isAssignable(SERVLET_APPLICATION_CONTEXT_CLASS, applicationContextClass)) { - return WebApplicationType.SERVLET; - } - if (isAssignable(REACTIVE_APPLICATION_CONTEXT_CLASS, applicationContextClass)) { - return WebApplicationType.REACTIVE; - } - return WebApplicationType.NONE; - } - - private static boolean isAssignable(String target, Class type) { - try { - return ClassUtils.resolveClassName(target, null).isAssignableFrom(type); - } - catch (Throwable ex) { - return false; - } - } - - private boolean isSslEnabled(ApplicationContext context) { - try { - AbstractReactiveWebServerFactory webServerFactory = context - .getBean(AbstractReactiveWebServerFactory.class); - return webServerFactory.getSsl() != null && webServerFactory.getSsl().isEnabled(); - } - catch (NoSuchBeanDefinitionException ex) { - return false; + BaseUrl baseUrl = new BaseUrlProviders(this.applicationContext).getBaseUrl(); + if (baseUrl != null) { + builder.baseUrl(baseUrl.resolve()); } + return builder.build(); } private void customizeWebTestClientBuilder(WebTestClient.Builder clientBuilder, ApplicationContext context) { - for (WebTestClientBuilderCustomizer customizer : context - .getBeansOfType(WebTestClientBuilderCustomizer.class) - .values()) { - customizer.customize(clientBuilder); - } - } - - private static final class WebTestClientCodecCustomizer { - - private static void customizeWebTestClientCodecs(WebTestClient.Builder clientBuilder, - ApplicationContext context) { - Collection codecCustomizers = context.getBeansOfType(CodecCustomizer.class).values(); - if (!CollectionUtils.isEmpty(codecCustomizers)) { - clientBuilder.exchangeStrategies(ExchangeStrategies.builder() - .codecs((codecs) -> codecCustomizers - .forEach((codecCustomizer) -> codecCustomizer.customize(codecs))) - .build()); - } - } - + Assert.state(this.applicationContext != null, "ApplicationContext not injected"); + getWebTestClientBuilderCustomizers(this.applicationContext) + .forEach((customizer) -> customizer.customize(clientBuilder)); + } + + private List getWebTestClientBuilderCustomizers(ApplicationContext context) { + List customizers = new ArrayList<>(); + SpringFactoriesLoader.forDefaultResourceLocation(context.getClassLoader()) + .load(WebTestClientBuilderCustomizer.class, ArgumentResolver.of(ApplicationContext.class, context)) + .forEach(customizers::add); + context.getBeansOfType(WebTestClientBuilderCustomizer.class).values().forEach(customizers::add); + return customizers; } } diff --git a/module/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerFactory.java b/core/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerFactory.java similarity index 96% rename from module/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerFactory.java rename to core/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerFactory.java index b9599400273..90cf1869805 100644 --- a/module/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerFactory.java +++ b/core/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerFactory.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.server.test.client.reactive; +package org.springframework.boot.test.web.reactive.client; import java.util.List; diff --git a/module/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/package-info.java b/core/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/client/package-info.java similarity index 92% rename from module/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/package-info.java rename to core/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/client/package-info.java index f5522d65012..76a491a8095 100644 --- a/module/spring-boot-web-server-test/src/main/java/org/springframework/boot/web/server/test/client/reactive/package-info.java +++ b/core/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/client/package-info.java @@ -19,6 +19,6 @@ * {@link org.springframework.test.web.reactive.server.WebTestClient}. */ @NullMarked -package org.springframework.boot.web.server.test.client.reactive; +package org.springframework.boot.test.web.reactive.client; import org.jspecify.annotations.NullMarked; diff --git a/core/spring-boot-test/src/main/resources/META-INF/spring.factories b/core/spring-boot-test/src/main/resources/META-INF/spring.factories index 5be7efde86a..fa085a63a02 100644 --- a/core/spring-boot-test/src/main/resources/META-INF/spring.factories +++ b/core/spring-boot-test/src/main/resources/META-INF/spring.factories @@ -4,7 +4,8 @@ org.springframework.boot.test.context.ImportsContextCustomizerFactory,\ org.springframework.boot.test.context.PropertyMappingContextCustomizerFactory,\ org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizerFactory,\ org.springframework.boot.test.context.filter.annotation.TypeExcludeFiltersContextCustomizerFactory,\ -org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory +org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory,\ +org.springframework.boot.test.web.reactive.client.WebTestClientContextCustomizerFactory # Application Context Initializers org.springframework.context.ApplicationContextInitializer=\ diff --git a/documentation/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withwebtestclient/MyWebTestClientBuilderCustomizerConfiguration.java b/documentation/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withwebtestclient/MyWebTestClientBuilderCustomizerConfiguration.java index 79718c1d351..9ba584cf2ce 100644 --- a/documentation/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withwebtestclient/MyWebTestClientBuilderCustomizerConfiguration.java +++ b/documentation/spring-boot-docs/src/main/java/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withwebtestclient/MyWebTestClientBuilderCustomizerConfiguration.java @@ -17,7 +17,7 @@ package org.springframework.boot.docs.testing.springbootapplications.autoconfiguredspringrestdocs.withwebtestclient; import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.web.server.test.client.reactive.WebTestClientBuilderCustomizer; +import org.springframework.boot.test.web.reactive.client.WebTestClientBuilderCustomizer; import org.springframework.context.annotation.Bean; import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.document; diff --git a/documentation/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withwebtestclient/MyWebTestClientBuilderCustomizerConfiguration.kt b/documentation/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withwebtestclient/MyWebTestClientBuilderCustomizerConfiguration.kt index b7f99bd9524..30825160813 100644 --- a/documentation/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withwebtestclient/MyWebTestClientBuilderCustomizerConfiguration.kt +++ b/documentation/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/testing/springbootapplications/autoconfiguredspringrestdocs/withwebtestclient/MyWebTestClientBuilderCustomizerConfiguration.kt @@ -17,7 +17,7 @@ package org.springframework.boot.docs.testing.springbootapplications.autoconfiguredspringrestdocs.withwebtestclient import org.springframework.boot.test.context.TestConfiguration -import org.springframework.boot.web.server.test.client.reactive.WebTestClientBuilderCustomizer +import org.springframework.boot.test.web.reactive.client.WebTestClientBuilderCustomizer import org.springframework.context.annotation.Bean import org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation import org.springframework.test.web.reactive.server.WebTestClient diff --git a/integration-test/spring-boot-test-integration-tests/build.gradle b/integration-test/spring-boot-test-integration-tests/build.gradle new file mode 100644 index 00000000000..014c524c6ba --- /dev/null +++ b/integration-test/spring-boot-test-integration-tests/build.gradle @@ -0,0 +1,33 @@ +/* + * Copyright 2012-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. + */ + + +plugins { + id "java-library" +} + +description = "Spring Boot Test Integration Tests" + +dependencies { + testImplementation(project(":core:spring-boot-test")) + testImplementation(project(":test-support:spring-boot-test-support")) + testImplementation(project(":module:spring-boot-http-codec")) + testImplementation(project(":module:spring-boot-tomcat")) + testImplementation(project(":module:spring-boot-web-server")) + testImplementation("io.projectreactor.netty:reactor-netty-http") + testImplementation("org.springframework:spring-webmvc") + testImplementation("org.springframework:spring-webflux") +} diff --git a/module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/NoWebTestClientBeanChecker.java b/integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/NoWebTestClientBeanChecker.java similarity index 96% rename from module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/NoWebTestClientBeanChecker.java rename to integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/NoWebTestClientBeanChecker.java index 89c55e62c48..039485bf5e1 100644 --- a/module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/NoWebTestClientBeanChecker.java +++ b/integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/NoWebTestClientBeanChecker.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.server.test.client.reactive; +package org.springframework.boot.test.web.reactive.client; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; diff --git a/module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerIntegrationTests.java b/integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerIntegrationTests.java similarity index 97% rename from module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerIntegrationTests.java rename to integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerIntegrationTests.java index c6ca610ca54..08ad57f5ce6 100644 --- a/module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerIntegrationTests.java +++ b/integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.server.test.client.reactive; +package org.springframework.boot.test.web.reactive.client; import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; diff --git a/module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerTcfCacheContextPausingTests.java b/integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerTcfCacheContextPausingTests.java similarity index 98% rename from module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerTcfCacheContextPausingTests.java rename to integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerTcfCacheContextPausingTests.java index adbdad6854b..99267d0cf9e 100644 --- a/module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerTcfCacheContextPausingTests.java +++ b/integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerTcfCacheContextPausingTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.server.test.client.reactive; +package org.springframework.boot.test.web.reactive.client; import java.util.Collections; import java.util.Map; diff --git a/module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerTests.java b/integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerTests.java similarity index 94% rename from module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerTests.java rename to integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerTests.java index e0280a9e9c0..71603526cce 100644 --- a/module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerTests.java +++ b/integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.server.test.client.reactive; +package org.springframework.boot.test.web.reactive.client; import org.junit.jupiter.api.Test; @@ -23,7 +23,7 @@ import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.web.server.test.client.reactive.WebTestClientContextCustomizer.WebTestClientRegistrar; +import org.springframework.boot.test.web.reactive.client.WebTestClientContextCustomizer.WebTestClientRegistrar; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.test.context.MergedContextConfiguration; diff --git a/module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithCustomBasePathTests.java b/integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerWithCustomBasePathTests.java similarity index 97% rename from module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithCustomBasePathTests.java rename to integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerWithCustomBasePathTests.java index f039b59b626..48e253e5b9a 100644 --- a/module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithCustomBasePathTests.java +++ b/integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerWithCustomBasePathTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.server.test.client.reactive; +package org.springframework.boot.test.web.reactive.client; import java.util.Collections; import java.util.Map; diff --git a/module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithCustomContextPathTests.java b/integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerWithCustomContextPathTests.java similarity index 97% rename from module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithCustomContextPathTests.java rename to integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerWithCustomContextPathTests.java index 04c278d79b4..33b1750ab04 100644 --- a/module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithCustomContextPathTests.java +++ b/integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerWithCustomContextPathTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.server.test.client.reactive; +package org.springframework.boot.test.web.reactive.client; import org.junit.jupiter.api.Test; diff --git a/module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithOverrideIntegrationTests.java b/integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerWithOverrideIntegrationTests.java similarity index 97% rename from module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithOverrideIntegrationTests.java rename to integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerWithOverrideIntegrationTests.java index a5e92eb24d3..175ea9ed8e1 100644 --- a/module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithOverrideIntegrationTests.java +++ b/integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerWithOverrideIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.server.test.client.reactive; +package org.springframework.boot.test.web.reactive.client; import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; diff --git a/module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithoutWebfluxIntegrationTests.java b/integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerWithoutWebfluxIntegrationTests.java similarity index 96% rename from module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithoutWebfluxIntegrationTests.java rename to integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerWithoutWebfluxIntegrationTests.java index bd81bbc26cb..e2af56eead6 100644 --- a/module/spring-boot-web-server-test/src/test/java/org/springframework/boot/web/server/test/client/reactive/WebTestClientContextCustomizerWithoutWebfluxIntegrationTests.java +++ b/integration-test/spring-boot-test-integration-tests/src/test/java/org/springframework/boot/test/web/reactive/client/WebTestClientContextCustomizerWithoutWebfluxIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.web.server.test.client.reactive; +package org.springframework.boot.test.web.reactive.client; import java.util.Collections; diff --git a/module/spring-boot-http-codec/build.gradle b/module/spring-boot-http-codec/build.gradle index 0d00da56d8f..ae0f6d0b243 100644 --- a/module/spring-boot-http-codec/build.gradle +++ b/module/spring-boot-http-codec/build.gradle @@ -29,6 +29,7 @@ dependencies { api("org.springframework:spring-web") optional(project(":core:spring-boot-autoconfigure")) + optional(project(":core:spring-boot-test")) optional(project(":module:spring-boot-jackson")) optional("org.springframework:spring-webflux") diff --git a/module/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/CodecWebTestClientBuilderCustomizer.java b/module/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/CodecWebTestClientBuilderCustomizer.java new file mode 100644 index 00000000000..1d946ef79de --- /dev/null +++ b/module/spring-boot-http-codec/src/main/java/org/springframework/boot/http/codec/CodecWebTestClientBuilderCustomizer.java @@ -0,0 +1,55 @@ +/* + * Copyright 2012-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.boot.http.codec; + +import java.util.Collection; +import java.util.function.Consumer; + +import org.springframework.boot.test.web.reactive.client.WebTestClientBuilderCustomizer; +import org.springframework.context.ApplicationContext; +import org.springframework.http.codec.ClientCodecConfigurer; +import org.springframework.test.web.reactive.server.WebTestClient.Builder; +import org.springframework.util.CollectionUtils; +import org.springframework.web.reactive.function.client.ExchangeStrategies; + +/** + * {@link WebTestClientBuilderCustomizer} to apply {@link CodecCustomizer} beans. + * + * @author Phillip Webb + */ +class CodecWebTestClientBuilderCustomizer implements WebTestClientBuilderCustomizer { + + private final ApplicationContext context; + + CodecWebTestClientBuilderCustomizer(ApplicationContext context) { + this.context = context; + } + + @Override + public void customize(Builder builder) { + Collection customizers = this.context.getBeansOfType(CodecCustomizer.class).values(); + if (!CollectionUtils.isEmpty(customizers)) { + ExchangeStrategies strategies = ExchangeStrategies.builder().codecs(apply(customizers)).build(); + builder.exchangeStrategies(strategies); + } + } + + private Consumer apply(Collection customizers) { + return (codecs) -> customizers.forEach((customizer) -> customizer.customize(codecs)); + } + +} diff --git a/module/spring-boot-http-codec/src/main/resources/META-INF/spring.factories b/module/spring-boot-http-codec/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000000..48faac4bcbd --- /dev/null +++ b/module/spring-boot-http-codec/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# WebTestClient Builder Customizers +org.springframework.boot.test.web.reactive.server.WebTestClientBuilderCustomizer=\ +org.springframework.boot.http.codec.CodecWebTestClientBuilderCustomizer diff --git a/module/spring-boot-restdocs/src/main/java/org/springframework/boot/restdocs/test/autoconfigure/RestDocsWebTestClientBuilderCustomizer.java b/module/spring-boot-restdocs/src/main/java/org/springframework/boot/restdocs/test/autoconfigure/RestDocsWebTestClientBuilderCustomizer.java index b8338e9e754..e09e5263ff8 100644 --- a/module/spring-boot-restdocs/src/main/java/org/springframework/boot/restdocs/test/autoconfigure/RestDocsWebTestClientBuilderCustomizer.java +++ b/module/spring-boot-restdocs/src/main/java/org/springframework/boot/restdocs/test/autoconfigure/RestDocsWebTestClientBuilderCustomizer.java @@ -18,7 +18,7 @@ package org.springframework.boot.restdocs.test.autoconfigure; import org.jspecify.annotations.Nullable; -import org.springframework.boot.web.server.test.client.reactive.WebTestClientBuilderCustomizer; +import org.springframework.boot.test.web.reactive.client.WebTestClientBuilderCustomizer; import org.springframework.restdocs.webtestclient.WebTestClientRestDocumentationConfigurer; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.util.StringUtils; diff --git a/module/spring-boot-web-server-test/src/main/resources/META-INF/spring.factories b/module/spring-boot-web-server-test/src/main/resources/META-INF/spring.factories index 7b66b762df7..aa63dda60b1 100644 --- a/module/spring-boot-web-server-test/src/main/resources/META-INF/spring.factories +++ b/module/spring-boot-web-server-test/src/main/resources/META-INF/spring.factories @@ -6,5 +6,4 @@ org.springframework.boot.web.server.test.SpringBootTestRandomPortEnvironmentPost org.springframework.test.context.ContextCustomizerFactory=\ org.springframework.boot.web.server.test.client.RestTestClientContextCustomizerFactory,\ org.springframework.boot.web.server.test.client.TestRestTemplateContextCustomizerFactory,\ -org.springframework.boot.web.server.test.client.reactive.WebTestClientContextCustomizerFactory,\ org.springframework.boot.web.server.test.reactor.netty.DisableReactorResourceFactoryGlobalResourcesContextCustomizerFactory diff --git a/module/spring-boot-web-server/build.gradle b/module/spring-boot-web-server/build.gradle index b684dfced6f..7e933e552dd 100644 --- a/module/spring-boot-web-server/build.gradle +++ b/module/spring-boot-web-server/build.gradle @@ -29,6 +29,7 @@ dependencies { api("org.springframework:spring-web") optional(project(":core:spring-boot-autoconfigure")) + optional(project(":core:spring-boot-test")) optional("io.projectreactor:reactor-core") optional("jakarta.servlet:jakarta.servlet-api") optional("org.springframework:spring-test") diff --git a/module/spring-boot-webflux-test/src/main/java/org/springframework/boot/webflux/test/autoconfigure/SpringBootWebTestClientBuilderCustomizer.java b/module/spring-boot-webflux-test/src/main/java/org/springframework/boot/webflux/test/autoconfigure/SpringBootWebTestClientBuilderCustomizer.java index c9a7e545c84..0b211c2d041 100644 --- a/module/spring-boot-webflux-test/src/main/java/org/springframework/boot/webflux/test/autoconfigure/SpringBootWebTestClientBuilderCustomizer.java +++ b/module/spring-boot-webflux-test/src/main/java/org/springframework/boot/webflux/test/autoconfigure/SpringBootWebTestClientBuilderCustomizer.java @@ -23,7 +23,7 @@ import java.util.function.Consumer; import org.jspecify.annotations.Nullable; import org.springframework.boot.http.codec.CodecCustomizer; -import org.springframework.boot.web.server.test.client.reactive.WebTestClientBuilderCustomizer; +import org.springframework.boot.test.web.reactive.client.WebTestClientBuilderCustomizer; import org.springframework.http.codec.ClientCodecConfigurer; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient.Builder; diff --git a/module/spring-boot-webflux-test/src/main/java/org/springframework/boot/webflux/test/autoconfigure/WebTestClientAutoConfiguration.java b/module/spring-boot-webflux-test/src/main/java/org/springframework/boot/webflux/test/autoconfigure/WebTestClientAutoConfiguration.java index 4125d53e52b..d27464c4638 100644 --- a/module/spring-boot-webflux-test/src/main/java/org/springframework/boot/webflux/test/autoconfigure/WebTestClientAutoConfiguration.java +++ b/module/spring-boot-webflux-test/src/main/java/org/springframework/boot/webflux/test/autoconfigure/WebTestClientAutoConfiguration.java @@ -26,7 +26,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.http.codec.CodecCustomizer; -import org.springframework.boot.web.server.test.client.reactive.WebTestClientBuilderCustomizer; +import org.springframework.boot.test.web.reactive.client.WebTestClientBuilderCustomizer; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.test.web.reactive.server.MockServerConfigurer; diff --git a/module/spring-boot-webmvc-test/src/main/java/org/springframework/boot/webmvc/test/autoconfigure/MockMvcAutoConfiguration.java b/module/spring-boot-webmvc-test/src/main/java/org/springframework/boot/webmvc/test/autoconfigure/MockMvcAutoConfiguration.java index d3cef4a06d1..b70016d4764 100644 --- a/module/spring-boot-webmvc-test/src/main/java/org/springframework/boot/webmvc/test/autoconfigure/MockMvcAutoConfiguration.java +++ b/module/spring-boot-webmvc-test/src/main/java/org/springframework/boot/webmvc/test/autoconfigure/MockMvcAutoConfiguration.java @@ -24,9 +24,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.web.reactive.client.WebTestClientBuilderCustomizer; +import org.springframework.boot.test.web.servlet.client.RestTestClientBuilderCustomizer; import org.springframework.boot.web.server.autoconfigure.ServerProperties; -import org.springframework.boot.web.server.test.client.RestTestClientBuilderCustomizer; -import org.springframework.boot.web.server.test.client.reactive.WebTestClientBuilderCustomizer; import org.springframework.boot.webmvc.autoconfigure.DispatcherServletPath; import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.boot.webmvc.autoconfigure.WebMvcProperties; diff --git a/module/spring-boot-webmvc-test/src/test/java/org/springframework/boot/webmvc/test/autoconfigure/MockMvcAutoConfigurationTests.java b/module/spring-boot-webmvc-test/src/test/java/org/springframework/boot/webmvc/test/autoconfigure/MockMvcAutoConfigurationTests.java index 85e4f80c112..22671c3c576 100644 --- a/module/spring-boot-webmvc-test/src/test/java/org/springframework/boot/webmvc/test/autoconfigure/MockMvcAutoConfigurationTests.java +++ b/module/spring-boot-webmvc-test/src/test/java/org/springframework/boot/webmvc/test/autoconfigure/MockMvcAutoConfigurationTests.java @@ -21,8 +21,8 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.test.web.reactive.client.WebTestClientBuilderCustomizer; import org.springframework.boot.web.server.test.client.RestTestClientBuilderCustomizer; -import org.springframework.boot.web.server.test.client.reactive.WebTestClientBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/settings.gradle b/settings.gradle index 97f524b86fb..8a47cc323cd 100644 --- a/settings.gradle +++ b/settings.gradle @@ -405,6 +405,7 @@ include ":integration-test:spring-boot-launch-script-integration-tests" include ":integration-test:spring-boot-loader-integration-tests" include ":integration-test:spring-boot-server-integration-tests" include ":integration-test:spring-boot-sni-integration-tests" +include ":integration-test:spring-boot-test-integration-tests" include ":system-test:spring-boot-deployment-system-tests" include ":system-test:spring-boot-image-system-tests"