Merge branch '2.7.x' into 3.0.x

This commit is contained in:
Phillip Webb
2023-02-21 23:15:40 -08:00
1890 changed files with 27173 additions and 21952 deletions

View File

@@ -153,7 +153,9 @@ public class SpringBootContextLoader extends AbstractContextLoader implements Ao
Assert.state(mergedConfig.getParent() == null,
() -> "UseMainMethod.%s cannot be used with @ContextHierarchy tests".formatted(useMainMethod));
Class<?> springBootConfiguration = Arrays.stream(mergedConfig.getClasses())
.filter(this::isSpringBootConfiguration).findFirst().orElse(null);
.filter(this::isSpringBootConfiguration)
.findFirst()
.orElse(null);
Assert.state(springBootConfiguration != null || useMainMethod == UseMainMethod.WHEN_AVAILABLE,
"Cannot use main method as no @SpringBootConfiguration-annotated class is available");
Method mainMethod = (springBootConfiguration != null)
@@ -174,7 +176,7 @@ public class SpringBootContextLoader extends AbstractContextLoader implements Ao
private boolean isSpringBootConfiguration(Class<?> candidate) {
return MergedAnnotations.from(candidate, SearchStrategy.TYPE_HIERARCHY)
.isPresent(SpringBootConfiguration.class);
.isPresent(SpringBootConfiguration.class);
}
private void configure(MergedContextConfiguration mergedConfig, SpringApplication application) {
@@ -296,7 +298,7 @@ public class SpringBootContextLoader extends AbstractContextLoader implements Ao
}
initializers.addAll(application.getInitializers());
for (Class<? extends ApplicationContextInitializer<?>> initializerClass : mergedConfig
.getContextInitializerClasses()) {
.getContextInitializerClasses()) {
initializers.add(BeanUtils.instantiateClass(initializerClass));
}
if (mergedConfig.getParent() != null) {
@@ -554,7 +556,8 @@ public class SpringBootContextLoader extends AbstractContextLoader implements Ao
throw ex;
}
List<ApplicationContext> rootContexts = this.contexts.stream()
.filter((context) -> context.getParent() == null).toList();
.filter((context) -> context.getParent() == null)
.toList();
Assert.state(!rootContexts.isEmpty(), "No root application context located");
Assert.state(rootContexts.size() == 1, "No unique root application context located");
return rootContexts.get(0);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-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.
@@ -187,6 +187,7 @@ public @interface SpringBootTest {
* Enumeration of how the main method of the
* {@link SpringBootConfiguration @SpringBootConfiguration}-annotated class is used
* when creating and running the {@link SpringApplication} under test.
*
* @since 3.0.0
*/
enum UseMainMethod {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-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.
@@ -49,11 +49,17 @@ public class SpringBootTestAotProcessor extends TestAotProcessor {
int requiredArgs = 6;
Assert.isTrue(args.length >= requiredArgs,
() -> "Usage: %s <classpathRoots> <sourceOutput> <resourceOutput> <classOutput> <groupId> <artifactId>"
.formatted(TestAotProcessor.class.getName()));
Set<Path> classpathRoots = Arrays.stream(args[0].split(File.pathSeparator)).map(Paths::get)
.collect(Collectors.toSet());
Settings settings = Settings.builder().sourceOutput(Paths.get(args[1])).resourceOutput(Paths.get(args[2]))
.classOutput(Paths.get(args[3])).groupId(args[4]).artifactId(args[5]).build();
.formatted(TestAotProcessor.class.getName()));
Set<Path> classpathRoots = Arrays.stream(args[0].split(File.pathSeparator))
.map(Paths::get)
.collect(Collectors.toSet());
Settings settings = Settings.builder()
.sourceOutput(Paths.get(args[1]))
.resourceOutput(Paths.get(args[2]))
.classOutput(Paths.get(args[3]))
.groupId(args[4])
.artifactId(args[5])
.build();
new SpringBootTestAotProcessor(classpathRoots, settings).process();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-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.
@@ -127,7 +127,7 @@ public class SpringBootTestContextBootstrapper extends DefaultTestContextBootstr
protected List<TestExecutionListener> getDefaultTestExecutionListeners() {
List<TestExecutionListener> listeners = new ArrayList<>(super.getDefaultTestExecutionListeners());
List<DefaultTestExecutionListenersPostProcessor> postProcessors = SpringFactoriesLoader
.loadFactories(DefaultTestExecutionListenersPostProcessor.class, getClass().getClassLoader());
.loadFactories(DefaultTestExecutionListenersPostProcessor.class, getClass().getClassLoader());
for (DefaultTestExecutionListenersPostProcessor postProcessor : postProcessors) {
listeners = postProcessor.postProcessDefaultTestExecutionListeners(listeners);
}
@@ -184,7 +184,7 @@ public class SpringBootTestContextBootstrapper extends DefaultTestContextBootstr
TestPropertySourceUtils.convertInlinedPropertiesToMap(configuration.getPropertySourceProperties()));
Binder binder = new Binder(source);
return binder.bind("spring.main.web-application-type", Bindable.of(WebApplicationType.class))
.orElseGet(this::deduceWebApplicationType);
.orElseGet(this::deduceWebApplicationType);
}
private WebApplicationType deduceWebApplicationType() {
@@ -211,8 +211,9 @@ public class SpringBootTestContextBootstrapper extends DefaultTestContextBootstr
*/
protected String determineResourceBasePath(MergedContextConfiguration configuration) {
return MergedAnnotations.from(configuration.getTestClass(), SearchStrategy.TYPE_HIERARCHY)
.get(WebAppConfiguration.class).getValue(MergedAnnotation.VALUE, String.class)
.orElse("src/main/webapp");
.get(WebAppConfiguration.class)
.getValue(MergedAnnotation.VALUE, String.class)
.orElse("src/main/webapp");
}
private boolean isWebEnvironmentSupported(MergedContextConfiguration mergedConfig) {
@@ -250,7 +251,7 @@ public class SpringBootTestContextBootstrapper extends DefaultTestContextBootstr
private Class<?> findConfigurationClass(Class<?> testClass) {
String propertyName = "%s.SpringBootConfiguration.%s"
.formatted(SpringBootTestContextBootstrapper.class.getName(), testClass.getName());
.formatted(SpringBootTestContextBootstrapper.class.getName(), testClass.getName());
String foundClassName = this.aotTestAttributes.getString(propertyName);
if (foundClassName != null) {
return ClassUtils.resolveClassName(foundClassName, testClass.getClassLoader());
@@ -265,7 +266,7 @@ public class SpringBootTestContextBootstrapper extends DefaultTestContextBootstr
private boolean containsNonTestComponent(Class<?>[] classes) {
for (Class<?> candidate : classes) {
if (!MergedAnnotations.from(candidate, SearchStrategy.INHERITED_ANNOTATIONS)
.isPresent(TestConfiguration.class)) {
.isPresent(TestConfiguration.class)) {
return true;
}
}
@@ -351,8 +352,9 @@ public class SpringBootTestContextBootstrapper extends DefaultTestContextBootstr
protected void verifyConfiguration(Class<?> testClass) {
SpringBootTest springBootTest = getAnnotation(testClass);
if (springBootTest != null && isListeningOnPort(springBootTest.webEnvironment()) && MergedAnnotations
.from(testClass, SearchStrategy.INHERITED_ANNOTATIONS).isPresent(WebAppConfiguration.class)) {
if (springBootTest != null && isListeningOnPort(springBootTest.webEnvironment())
&& MergedAnnotations.from(testClass, SearchStrategy.INHERITED_ANNOTATIONS)
.isPresent(WebAppConfiguration.class)) {
throw new IllegalStateException("@WebAppConfiguration should only be used "
+ "with @SpringBootTest when @SpringBootTest is configured with a "
+ "mock web environment. Please remove @WebAppConfiguration or reconfigure @SpringBootTest.");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-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.
@@ -223,7 +223,7 @@ public class ApplicationContextAssert<C extends ApplicationContext>
throwAssertionError(contextFailedToStartWhenExpecting("to get beans names with type:%n <%s>", type));
}
return Assertions.assertThat(getApplicationContext().getBeanNamesForType(type))
.as("Bean names of type <%s> from <%s>", type, getApplicationContext());
.as("Bean names of type <%s> from <%s>", type, getApplicationContext());
}
/**
@@ -359,8 +359,8 @@ public class ApplicationContextAssert<C extends ApplicationContext>
"%nExpecting:%n <%s>%nto contain a bean of name:%n <%s> (%s)%nbut found:%n <%s> of type <%s>",
getApplicationContext(), name, type, bean, bean.getClass()));
}
return Assertions.assertThat((T) bean).as("Bean of name <%s> and type <%s> from <%s>", name, type,
getApplicationContext());
return Assertions.assertThat((T) bean)
.as("Bean of name <%s> and type <%s> from <%s>", name, type, getApplicationContext());
}
private Object findBean(String name) {
@@ -411,7 +411,7 @@ public class ApplicationContextAssert<C extends ApplicationContext>
throwAssertionError(contextFailedToStartWhenExpecting("to get beans of type:%n <%s>", type));
}
return Assertions.assertThat(scope.getBeansOfType(getApplicationContext(), type))
.as("Beans of type <%s> from <%s>", type, getApplicationContext());
.as("Beans of type <%s> from <%s>", type, getApplicationContext());
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-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.
@@ -96,9 +96,9 @@ class AssertProviderApplicationContextInvocationHandler implements InvocationHan
+ this.startupFailure.getClass().getName() + "]";
}
ToStringCreator builder = new ToStringCreator(this.applicationContext)
.append("id", this.applicationContext.getId())
.append("applicationName", this.applicationContext.getApplicationName())
.append("beanDefinitionCount", this.applicationContext.getBeanDefinitionCount());
.append("id", this.applicationContext.getId())
.append("applicationName", this.applicationContext.getApplicationName())
.append("beanDefinitionCount", this.applicationContext.getBeanDefinitionCount());
return "Started application " + builder;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-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.
@@ -338,7 +338,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@SuppressWarnings("unchecked")
public SELF run(ContextConsumer<? super A> consumer) {
withContextClassLoader(this.runnerConfiguration.classLoader, () -> this.runnerConfiguration.systemProperties
.applyToSystemProperties(() -> consumeAssertableContext(true, consumer)));
.applyToSystemProperties(() -> consumeAssertableContext(true, consumer)));
return (SELF) this;
}
@@ -354,7 +354,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@SuppressWarnings("unchecked")
public SELF prepare(ContextConsumer<? super A> consumer) {
withContextClassLoader(this.runnerConfiguration.classLoader, () -> this.runnerConfiguration.systemProperties
.applyToSystemProperties(() -> consumeAssertableContext(false, consumer)));
.applyToSystemProperties(() -> consumeAssertableContext(false, consumer)));
return (SELF) this;
}
@@ -396,7 +396,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
autowireCapableBeanFactory.setAllowCircularReferences(this.runnerConfiguration.allowCircularReferences);
if (beanFactory instanceof DefaultListableBeanFactory listableBeanFactory) {
listableBeanFactory
.setAllowBeanDefinitionOverriding(this.runnerConfiguration.allowBeanDefinitionOverriding);
.setAllowBeanDefinitionOverriding(this.runnerConfiguration.allowBeanDefinitionOverriding);
}
}
try {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2022 the original author or authors.
* Copyright 2020-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.
@@ -210,7 +210,7 @@ class HttpGraphQlTesterContextCustomizer implements ContextCustomizer {
private boolean isSslEnabled(ApplicationContext context) {
try {
AbstractConfigurableWebServerFactory webServerFactory = context
.getBean(AbstractConfigurableWebServerFactory.class);
.getBean(AbstractConfigurableWebServerFactory.class);
return webServerFactory.getSsl() != null && webServerFactory.getSsl().isEnabled();
}
catch (NoSuchBeanDefinitionException ex) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-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.
@@ -96,8 +96,10 @@ public class JacksonTester<T> extends AbstractJsonMarshalTester<T> {
@Override
protected JsonContent<T> getJsonContent(String json) {
Configuration configuration = Configuration.builder().jsonProvider(new JacksonJsonProvider(this.objectMapper))
.mappingProvider(new JacksonMappingProvider(this.objectMapper)).build();
Configuration configuration = Configuration.builder()
.jsonProvider(new JacksonJsonProvider(this.objectMapper))
.mappingProvider(new JacksonMappingProvider(this.objectMapper))
.build();
return new JsonContent<>(getResourceLoadClass(), getType(), json, configuration);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-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.
@@ -67,10 +67,12 @@ class DefinitionsParser {
private void parseElement(AnnotatedElement element, Class<?> source) {
MergedAnnotations annotations = MergedAnnotations.from(element, SearchStrategy.SUPERCLASS);
annotations.stream(MockBean.class).map(MergedAnnotation::synthesize)
.forEach((annotation) -> parseMockBeanAnnotation(annotation, element, source));
annotations.stream(SpyBean.class).map(MergedAnnotation::synthesize)
.forEach((annotation) -> parseSpyBeanAnnotation(annotation, element, source));
annotations.stream(MockBean.class)
.map(MergedAnnotation::synthesize)
.forEach((annotation) -> parseMockBeanAnnotation(annotation, element, source));
annotations.stream(SpyBean.class)
.map(MergedAnnotation::synthesize)
.forEach((annotation) -> parseSpyBeanAnnotation(annotation, element, source));
}
private void parseMockBeanAnnotation(MockBean annotation, AnnotatedElement element, Class<?> source) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-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.
@@ -129,9 +129,13 @@ class MockDefinition extends Definition {
@Override
public String toString() {
return new ToStringCreator(this).append("name", getName()).append("typeToMock", this.typeToMock)
.append("extraInterfaces", this.extraInterfaces).append("answer", this.answer)
.append("serializable", this.serializable).append("reset", getReset()).toString();
return new ToStringCreator(this).append("name", getName())
.append("typeToMock", this.typeToMock)
.append("extraInterfaces", this.extraInterfaces)
.append("answer", this.answer)
.append("serializable", this.serializable)
.append("reset", getReset())
.toString();
}
<T> T createMock() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-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.
@@ -83,7 +83,7 @@ public class MockitoPostProcessor implements InstantiationAwareBeanPostProcessor
private static final String BEAN_NAME = MockitoPostProcessor.class.getName();
private static final String CONFIGURATION_CLASS_ATTRIBUTE = Conventions
.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "configurationClass");
.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "configurationClass");
private static final BeanNameGenerator beanNameGenerator = new DefaultBeanNameGenerator();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-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.
@@ -108,7 +108,7 @@ public class MockitoTestExecutionListener extends AbstractTestExecutionListener
parser.parse(testContext.getTestClass());
if (!parser.getDefinitions().isEmpty()) {
MockitoPostProcessor postProcessor = testContext.getApplicationContext()
.getBean(MockitoPostProcessor.class);
.getBean(MockitoPostProcessor.class);
for (Definition definition : parser.getDefinitions()) {
Field field = parser.getField(definition);
if (field != null) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-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.
@@ -79,8 +79,10 @@ class SpyDefinition extends Definition {
@Override
public String toString() {
return new ToStringCreator(this).append("name", getName()).append("typeToSpy", this.typeToSpy)
.append("reset", getReset()).toString();
return new ToStringCreator(this).append("name", getName())
.append("typeToSpy", this.typeToSpy)
.append("reset", getReset())
.toString();
}
<T> T createSpy(Object instance) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-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.
@@ -44,7 +44,7 @@ class SpringBootTestRandomPortEnvironmentPostProcessor implements EnvironmentPos
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
MapPropertySource source = (MapPropertySource) environment.getPropertySources()
.get(TestPropertySourceUtils.INLINED_PROPERTIES_PROPERTY_SOURCE_NAME);
.get(TestPropertySourceUtils.INLINED_PROPERTIES_PROPERTY_SOURCE_NAME);
if (source == null || isTestServerPortFixed(source, environment) || isTestManagementPortConfigured(source)) {
return;
}
@@ -70,10 +70,14 @@ class SpringBootTestRandomPortEnvironmentPostProcessor implements EnvironmentPos
}
private Integer getPropertyAsInteger(ConfigurableEnvironment environment, String property, Integer defaultValue) {
return environment.getPropertySources().stream().filter(
(source) -> !source.getName().equals(TestPropertySourceUtils.INLINED_PROPERTIES_PROPERTY_SOURCE_NAME))
.map((source) -> getPropertyAsInteger(source, property, environment)).filter(Objects::nonNull)
.findFirst().orElse(defaultValue);
return environment.getPropertySources()
.stream()
.filter((source) -> !source.getName()
.equals(TestPropertySourceUtils.INLINED_PROPERTIES_PROPERTY_SOURCE_NAME))
.map((source) -> getPropertyAsInteger(source, property, environment))
.filter(Objects::nonNull)
.findFirst()
.orElse(defaultValue);
}
private Integer getPropertyAsInteger(PropertySource<?> source, String property,

View File

@@ -964,12 +964,12 @@ public class TestRestTemplate {
private URI resolveUri(RequestEntity<?> entity) {
if (entity instanceof UriTemplateRequestEntity<?> templatedUriEntity) {
if (templatedUriEntity.getVars() != null) {
return this.restTemplate.getUriTemplateHandler().expand(templatedUriEntity.getUriTemplate(),
templatedUriEntity.getVars());
return this.restTemplate.getUriTemplateHandler()
.expand(templatedUriEntity.getUriTemplate(), templatedUriEntity.getVars());
}
else if (templatedUriEntity.getVarsMap() != null) {
return this.restTemplate.getUriTemplateHandler().expand(templatedUriEntity.getUriTemplate(),
templatedUriEntity.getVarsMap());
return this.restTemplate.getUriTemplateHandler()
.expand(templatedUriEntity.getUriTemplate(), templatedUriEntity.getVarsMap());
}
throw new IllegalStateException(
"No variables specified for URI template: " + templatedUriEntity.getUriTemplate());
@@ -1046,7 +1046,8 @@ public class TestRestTemplate {
}
if (readTimeout != null) {
SocketConfig socketConfig = SocketConfig.custom()
.setSoTimeout((int) readTimeout.toMillis(), TimeUnit.MILLISECONDS).build();
.setSoTimeout((int) readTimeout.toMillis(), TimeUnit.MILLISECONDS)
.build();
builder.setDefaultSocketConfig(socketConfig);
}
return builder.build();
@@ -1055,9 +1056,11 @@ public class TestRestTemplate {
private SSLConnectionSocketFactory createSocketFactory()
throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy())
.build();
return SSLConnectionSocketFactoryBuilder.create().setSslContext(sslContext)
.setTlsVersions(TLS.V_1_3, TLS.V_1_2).build();
.build();
return SSLConnectionSocketFactoryBuilder.create()
.setSslContext(sslContext)
.setTlsVersions(TLS.V_1_3, TLS.V_1_2)
.build();
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-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.
@@ -57,7 +57,7 @@ class TestRestTemplateContextCustomizer implements ContextCustomizer {
return;
}
SpringBootTest springBootTest = TestContextAnnotationUtils
.findMergedAnnotation(mergedContextConfiguration.getTestClass(), SpringBootTest.class);
.findMergedAnnotation(mergedContextConfiguration.getTestClass(), SpringBootTest.class);
if (springBootTest.webEnvironment().isEmbedded()) {
registerTestRestTemplate(context);
}
@@ -150,7 +150,7 @@ class TestRestTemplateContextCustomizer implements ContextCustomizer {
private boolean isSslEnabled(ApplicationContext context) {
try {
AbstractServletWebServerFactory webServerFactory = context
.getBean(AbstractServletWebServerFactory.class);
.getBean(AbstractServletWebServerFactory.class);
return webServerFactory.getSsl() != null && webServerFactory.getSsl().isEnabled();
}
catch (NoSuchBeanDefinitionException ex) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-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.
@@ -215,7 +215,7 @@ class WebTestClientContextCustomizer implements ContextCustomizer {
private boolean isSslEnabled(ApplicationContext context) {
try {
AbstractReactiveWebServerFactory webServerFactory = context
.getBean(AbstractReactiveWebServerFactory.class);
.getBean(AbstractReactiveWebServerFactory.class);
return webServerFactory.getSsl() != null && webServerFactory.getSsl().isEnabled();
}
catch (NoSuchBeanDefinitionException ex) {
@@ -225,7 +225,8 @@ class WebTestClientContextCustomizer implements ContextCustomizer {
private void customizeWebTestClientBuilder(WebTestClient.Builder clientBuilder, ApplicationContext context) {
for (WebTestClientBuilderCustomizer customizer : context
.getBeansOfType(WebTestClientBuilderCustomizer.class).values()) {
.getBeansOfType(WebTestClientBuilderCustomizer.class)
.values()) {
customizer.customize(clientBuilder);
}
}
@@ -233,9 +234,10 @@ class WebTestClientContextCustomizer implements ContextCustomizer {
private void customizeWebTestClientCodecs(WebTestClient.Builder clientBuilder, ApplicationContext context) {
Collection<CodecCustomizer> codecCustomizers = context.getBeansOfType(CodecCustomizer.class).values();
if (!CollectionUtils.isEmpty(codecCustomizers)) {
clientBuilder.exchangeStrategies(ExchangeStrategies.builder().codecs(
(codecs) -> codecCustomizers.forEach((codecCustomizer) -> codecCustomizer.customize(codecs)))
.build());
clientBuilder.exchangeStrategies(ExchangeStrategies.builder()
.codecs((codecs) -> codecCustomizers
.forEach((codecCustomizer) -> codecCustomizer.customize(codecs)))
.build());
}
}