mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-09-17 20:19:06 +00:00
Introduce spring-boot-webclient-test
See gh-46356 See gh-47322
This commit is contained in:
@@ -128,6 +128,7 @@ dependencies {
|
||||
implementation(project(path: ":module:spring-boot-security"))
|
||||
implementation(project(path: ":module:spring-boot-tomcat"))
|
||||
implementation(project(path: ":module:spring-boot-webclient"))
|
||||
implementation(project(path: ":module:spring-boot-webclient-test"))
|
||||
implementation(project(path: ":module:spring-boot-webflux"))
|
||||
implementation(project(path: ":module:spring-boot-webflux-test"))
|
||||
implementation(project(path: ":module:spring-boot-webmvc"))
|
||||
|
||||
+14
@@ -729,6 +729,20 @@ include-code::MyRestClientServiceTests[]
|
||||
|
||||
|
||||
|
||||
[[testing.spring-boot-applications.autoconfigured-web-client]]
|
||||
== Auto-configured Web Clients
|
||||
|
||||
You can use the javadoc:org.springframework.boot.webclient.test.autoconfigure.WebClientTest[format=annotation] annotation from the `spring-boot-webclient-test` module to test code that uses `WebClient`.
|
||||
By default, it auto-configures Jackson, GSON, and Jsonb support, and configures a javadoc:org.springframework.web.reactive.function.client.WebClient$Builder[].
|
||||
Regular javadoc:org.springframework.stereotype.Component[format=annotation] and javadoc:org.springframework.boot.context.properties.ConfigurationProperties[format=annotation] beans are not scanned when the javadoc:org.springframework.boot.webclient.test.autoconfigure.WebClientTest[format=annotation] annotation is used.
|
||||
javadoc:org.springframework.boot.context.properties.EnableConfigurationProperties[format=annotation] can be used to include javadoc:org.springframework.boot.context.properties.ConfigurationProperties[format=annotation] beans.
|
||||
|
||||
TIP: A list of the auto-configuration settings that are enabled by javadoc:org.springframework.boot.webclient.test.autoconfigure.WebClientTest[format=annotation] can be xref:appendix:test-auto-configuration/index.adoc[found in the appendix].
|
||||
|
||||
The specific beans that you want to test should be specified by using the `value` or `components` attribute of javadoc:org.springframework.boot.webclient.test.autoconfigure.WebClientTest[format=annotation].
|
||||
|
||||
|
||||
|
||||
[[testing.spring-boot-applications.autoconfigured-spring-restdocs]]
|
||||
== Auto-configured Spring REST Docs Tests
|
||||
|
||||
|
||||
+3
@@ -64,6 +64,9 @@ Spring Boot offers several focused, feature-specific `-test` modules:
|
||||
|`spring-boot-security-test`
|
||||
|Testing applications that use Spring Security.
|
||||
|
||||
|`spring-boot-webclient-test`
|
||||
|Testing applications that use `WebClient`. Provides the `@WebClientTest` test slice.
|
||||
|
||||
|`spring-boot-webflux-test`
|
||||
|Testing applications that use Spring WebFlux. Provides the `@WebFluxTest` test slice.
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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"
|
||||
id "org.springframework.boot.deployed"
|
||||
id "org.springframework.boot.optional-dependencies"
|
||||
id "org.springframework.boot.test-slice"
|
||||
}
|
||||
|
||||
description = "Spring Boot WebClient Test"
|
||||
|
||||
dependencies {
|
||||
api(project(":core:spring-boot-test-autoconfigure"))
|
||||
api(project(":module:spring-boot-webclient"))
|
||||
|
||||
optional(project(":core:spring-boot-autoconfigure"))
|
||||
optional(project(":module:spring-boot-jackson"))
|
||||
optional("org.apache.httpcomponents.client5:httpclient5")
|
||||
optional("org.junit.jupiter:junit-jupiter-api")
|
||||
optional("org.springframework:spring-test")
|
||||
|
||||
testImplementation(project(":core:spring-boot-test"))
|
||||
testImplementation(project(":module:spring-boot-micrometer-metrics"))
|
||||
testImplementation(project(":test-support:spring-boot-test-support"))
|
||||
testImplementation("com.squareup.okhttp3:mockwebserver")
|
||||
|
||||
testRuntimeOnly("ch.qos.logback:logback-classic")
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.webclient.test.autoconfigure;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.json.AutoConfigureJson;
|
||||
import org.springframework.web.client.RestClient.Builder;
|
||||
|
||||
/**
|
||||
* Annotation that can be applied to a test class to enable auto-configuration of a
|
||||
* {@link Builder WebClient.Builder}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@AutoConfigureJson
|
||||
@ImportAutoConfiguration
|
||||
public @interface AutoConfigureWebClient {
|
||||
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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.webclient.test.autoconfigure;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration;
|
||||
import org.springframework.boot.test.context.filter.annotation.TypeExcludeFilters;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.test.context.BootstrapWith;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.web.client.RestClient.Builder;
|
||||
|
||||
/**
|
||||
* Annotation for a Spring WebClient test that focuses <strong>only</strong> on beans that
|
||||
* use {@link Builder WebClient.Builder}.
|
||||
* <p>
|
||||
* Using this annotation only enables auto-configuration that is relevant to rest client
|
||||
* tests. Similarly, component scanning is limited to beans annotated with:
|
||||
* <ul>
|
||||
* <li>{@code @JsonComponent}</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* as well as beans that implement:
|
||||
* <ul>
|
||||
* <li>{@code JacksonModule}, if Jackson is available</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* When using JUnit 4, this annotation should be used in combination with
|
||||
* {@code @RunWith(SpringRunner.class)}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@BootstrapWith(WebClientTestContextBootstrapper.class)
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@OverrideAutoConfiguration(enabled = false)
|
||||
@TypeExcludeFilters(WebClientTypeExcludeFilter.class)
|
||||
@AutoConfigureWebClient
|
||||
@ImportAutoConfiguration
|
||||
public @interface WebClientTest {
|
||||
|
||||
/**
|
||||
* Properties in form {@literal key=value} that should be added to the Spring
|
||||
* {@link Environment} before the test runs.
|
||||
* @return the properties to add
|
||||
*/
|
||||
String[] properties() default {};
|
||||
|
||||
/**
|
||||
* Specifies the components to test. This is an alias of {@link #components()} which
|
||||
* can be used for brevity if no other attributes are defined. See
|
||||
* {@link #components()} for details.
|
||||
* @see #components()
|
||||
* @return the components to test
|
||||
*/
|
||||
@AliasFor("components")
|
||||
Class<?>[] value() default {};
|
||||
|
||||
/**
|
||||
* Specifies the components to test. May be left blank if components will be manually
|
||||
* imported or created directly.
|
||||
* @see #value()
|
||||
* @return the components to test
|
||||
*/
|
||||
@AliasFor("value")
|
||||
Class<?>[] components() default {};
|
||||
|
||||
/**
|
||||
* Determines if default filtering should be used with
|
||||
* {@link SpringBootApplication @SpringBootApplication}. By default only
|
||||
* {@code @JsonComponent} and {@code Module} beans are included.
|
||||
* @see #includeFilters()
|
||||
* @see #excludeFilters()
|
||||
* @return if default filters should be used
|
||||
*/
|
||||
boolean useDefaultFilters() default true;
|
||||
|
||||
/**
|
||||
* A set of include filters which can be used to add otherwise filtered beans to the
|
||||
* application context.
|
||||
* @return include filters to apply
|
||||
*/
|
||||
ComponentScan.Filter[] includeFilters() default {};
|
||||
|
||||
/**
|
||||
* A set of exclude filters which can be used to filter beans that would otherwise be
|
||||
* added to the application context.
|
||||
* @return exclude filters to apply
|
||||
*/
|
||||
ComponentScan.Filter[] excludeFilters() default {};
|
||||
|
||||
/**
|
||||
* Auto-configuration exclusions that should be applied for this test.
|
||||
* @return auto-configuration exclusions to apply
|
||||
*/
|
||||
@AliasFor(annotation = ImportAutoConfiguration.class, attribute = "exclude")
|
||||
Class<?>[] excludeAutoConfiguration() default {};
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.webclient.test.autoconfigure;
|
||||
|
||||
import org.springframework.boot.test.autoconfigure.TestSliceTestContextBootstrapper;
|
||||
import org.springframework.test.context.TestContextBootstrapper;
|
||||
|
||||
/**
|
||||
* {@link TestContextBootstrapper} for {@link WebClientTest @WebClientTest} support.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class WebClientTestContextBootstrapper extends TestSliceTestContextBootstrapper<WebClientTest> {
|
||||
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.webclient.test.autoconfigure;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.boot.context.TypeExcludeFilter;
|
||||
import org.springframework.boot.jackson.JsonComponent;
|
||||
import org.springframework.boot.test.context.filter.annotation.StandardAnnotationCustomizableTypeExcludeFilter;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link TypeExcludeFilter} for {@link WebClientTest @WebClientTest}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class WebClientTypeExcludeFilter extends StandardAnnotationCustomizableTypeExcludeFilter<WebClientTest> {
|
||||
|
||||
private static final Class<?>[] NO_COMPONENTS = {};
|
||||
|
||||
private static final String DATABIND_MODULE_CLASS_NAME = "tools.jackson.databind.JacksonModule";
|
||||
|
||||
private static final Set<Class<?>> KNOWN_INCLUDES;
|
||||
|
||||
static {
|
||||
Set<Class<?>> includes = new LinkedHashSet<>();
|
||||
if (ClassUtils.isPresent(DATABIND_MODULE_CLASS_NAME, WebClientTypeExcludeFilter.class.getClassLoader())) {
|
||||
try {
|
||||
includes.add(Class.forName(DATABIND_MODULE_CLASS_NAME, true,
|
||||
WebClientTypeExcludeFilter.class.getClassLoader()));
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
throw new IllegalStateException("Failed to load " + DATABIND_MODULE_CLASS_NAME, ex);
|
||||
}
|
||||
includes.add(JsonComponent.class);
|
||||
}
|
||||
KNOWN_INCLUDES = Collections.unmodifiableSet(includes);
|
||||
}
|
||||
|
||||
private final Class<?>[] components;
|
||||
|
||||
WebClientTypeExcludeFilter(Class<?> testClass) {
|
||||
super(testClass);
|
||||
this.components = getAnnotation().getValue("components", Class[].class).orElse(NO_COMPONENTS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getKnownIncludes() {
|
||||
return KNOWN_INCLUDES;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getComponentIncludes() {
|
||||
return new LinkedHashSet<>(Arrays.asList(this.components));
|
||||
}
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for web clients.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.boot.webclient.test.autoconfigure;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration
|
||||
org.springframework.boot.webclient.autoconfigure.WebClientAutoConfiguration
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.webclient.test.autoconfigure;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* A second example web client used with {@link WebClientTest @WebClientTest} tests.
|
||||
*
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
@Service
|
||||
public class AnotherExampleWebClientService {
|
||||
|
||||
private final WebClient.Builder builder;
|
||||
|
||||
private final WebClient webClient;
|
||||
|
||||
public AnotherExampleWebClientService(WebClient.Builder builder) {
|
||||
this.builder = builder;
|
||||
this.webClient = builder.baseUrl("https://example.com").build();
|
||||
}
|
||||
|
||||
protected WebClient.Builder geWebClientBuilder() {
|
||||
return this.builder;
|
||||
}
|
||||
|
||||
public String test() {
|
||||
return this.webClient.get().uri("/test").retrieve().toEntity(String.class).block().getBody();
|
||||
}
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.webclient.test.autoconfigure;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.bind.ConstructorBinding;
|
||||
import org.springframework.boot.context.properties.bind.DefaultValue;
|
||||
|
||||
/**
|
||||
* Example {@link ConstructorBinding constructor-bound}
|
||||
* {@link ConfigurationProperties @ConfigurationProperties} used to test the use of
|
||||
* configuration properties scan with sliced test.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@ConfigurationProperties("example")
|
||||
public class ExampleProperties {
|
||||
|
||||
private final String name;
|
||||
|
||||
public ExampleProperties(@DefaultValue("test") String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.webclient.test.autoconfigure;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
|
||||
|
||||
/**
|
||||
* Example {@link SpringBootApplication @SpringBootApplication} used with
|
||||
* {@link WebClientTest @WebClientTest} tests.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@ConfigurationPropertiesScan
|
||||
public class ExampleWebClientApplication {
|
||||
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.webclient.test.autoconfigure;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* Example web client using {@code WebClient} with {@link WebClientTest @WebClientTest}
|
||||
* tests.
|
||||
*
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
@Service
|
||||
public class ExampleWebClientService {
|
||||
|
||||
private final WebClient.Builder builder;
|
||||
|
||||
private final WebClient webClient;
|
||||
|
||||
public ExampleWebClientService(WebClient.Builder builder) {
|
||||
this.builder = builder;
|
||||
this.webClient = builder.build();
|
||||
}
|
||||
|
||||
protected WebClient.Builder getWebClientBuilder() {
|
||||
return this.builder;
|
||||
}
|
||||
|
||||
public String test() {
|
||||
return this.webClient.get().uri("/test").retrieve().toEntity(String.class).block().getBody();
|
||||
}
|
||||
|
||||
public void testPostWithBody(String body) {
|
||||
this.webClient.post().uri("/test").bodyValue(body).retrieve().toBodilessEntity().block();
|
||||
}
|
||||
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.webclient.test.autoconfigure;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
|
||||
import okhttp3.mockwebserver.MockWebServer;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.boot.webclient.WebClientCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* Configuration for a {@link MockWebServer}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class MockWebServerConfiguration implements DisposableBean, WebClientCustomizer {
|
||||
|
||||
private final MockWebServer mockWebServer = new MockWebServer();
|
||||
|
||||
MockWebServerConfiguration() {
|
||||
try {
|
||||
this.mockWebServer.start();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new UncheckedIOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
try {
|
||||
this.mockWebServer.shutdown();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new UncheckedIOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(WebClient.Builder webClientBuilder) {
|
||||
webClientBuilder.baseUrl(this.mockWebServer.url("/").toString());
|
||||
}
|
||||
|
||||
@Bean
|
||||
MockWebServer mockWebServer() {
|
||||
return this.mockWebServer;
|
||||
}
|
||||
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.webclient.test.autoconfigure;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import okhttp3.mockwebserver.MockResponse;
|
||||
import okhttp3.mockwebserver.MockWebServer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link WebClientTest @WebClientTest}.
|
||||
*
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
@WebClientTest(ExampleWebClientService.class)
|
||||
@Import(MockWebServerConfiguration.class)
|
||||
class WebClientTestIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private MockWebServer server;
|
||||
|
||||
@Autowired
|
||||
private ExampleWebClientService client;
|
||||
|
||||
@Test
|
||||
void mockServerCall1() throws InterruptedException {
|
||||
this.server.enqueue(new MockResponse().setBody("1"));
|
||||
assertThat(this.client.test()).isEqualTo("1");
|
||||
this.server.takeRequest();
|
||||
}
|
||||
|
||||
@Test
|
||||
void mockServerCall2() throws InterruptedException {
|
||||
this.server.enqueue(new MockResponse().setBody("2"));
|
||||
assertThat(this.client.test()).isEqualTo("2");
|
||||
this.server.takeRequest();
|
||||
}
|
||||
|
||||
@Test
|
||||
void mockServerCallWithContent() throws InterruptedException {
|
||||
this.server.enqueue(new MockResponse().setBody("1"));
|
||||
this.client.testPostWithBody("test");
|
||||
assertThat(this.server.takeRequest().getBody().readString(StandardCharsets.UTF_8)).isEqualTo("test");
|
||||
}
|
||||
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.webclient.test.autoconfigure;
|
||||
|
||||
import okhttp3.mockwebserver.MockResponse;
|
||||
import okhttp3.mockwebserver.MockWebServer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Tests for {@link WebClientTest @WebClientTest} with no specific client.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@WebClientTest
|
||||
@Import(MockWebServerConfiguration.class)
|
||||
class WebClientTestNoComponentIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private MockWebServer server;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
private WebClient.Builder webClientBuilder;
|
||||
|
||||
@Test
|
||||
void exampleWebClientServiceIsNotInjected() {
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||
.isThrownBy(() -> this.applicationContext.getBean(ExampleWebClientService.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void examplePropertiesIsNotInjected() {
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||
.isThrownBy(() -> this.applicationContext.getBean(ExampleProperties.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void manuallyCreateBean() throws InterruptedException {
|
||||
ExampleWebClientService client = new ExampleWebClientService(this.webClientBuilder);
|
||||
this.server.enqueue(new MockResponse().setBody("hello"));
|
||||
assertThat(client.test()).isEqualTo("hello");
|
||||
this.server.takeRequest();
|
||||
}
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.webclient.test.autoconfigure;
|
||||
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for the {@link WebClientTest#properties properties} attribute of
|
||||
* {@link WebClientTest @WebClientTest}.
|
||||
*
|
||||
* @author Artsiom Yudovin
|
||||
*/
|
||||
@WebClientTest(properties = "spring.profiles.active=test")
|
||||
class WebClientTestPropertiesIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
@Test
|
||||
void environmentWithNewProfile() {
|
||||
assertThat(this.environment.getActiveProfiles()).containsExactly("test");
|
||||
}
|
||||
|
||||
@Nested
|
||||
class NestedTests {
|
||||
|
||||
@Autowired
|
||||
private Environment innerEnvironment;
|
||||
|
||||
@Test
|
||||
void propertiesFromEnclosingClassAffectNestedTests() {
|
||||
assertThat(WebClientTestPropertiesIntegrationTests.this.environment.getActiveProfiles())
|
||||
.containsExactly("test");
|
||||
assertThat(this.innerEnvironment.getActiveProfiles()).containsExactly("test");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.webclient.test.autoconfigure;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link WebClientTest @WebClientTest} with a
|
||||
* {@link ConfigurationProperties @ConfigurationProperties} annotated type.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@WebClientTest(components = ExampleProperties.class, properties = "example.name=Hello")
|
||||
class WebClientTestWithConfigurationPropertiesIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Test
|
||||
void configurationPropertiesCanBeAddedAsComponent() {
|
||||
assertThat(this.applicationContext.getBeansOfType(ExampleProperties.class).keySet())
|
||||
.containsOnly("example-" + ExampleProperties.class.getName());
|
||||
assertThat(this.applicationContext.getBean(ExampleProperties.class).getName()).isEqualTo("Hello");
|
||||
}
|
||||
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.webclient.test.autoconfigure;
|
||||
|
||||
import okhttp3.mockwebserver.MockResponse;
|
||||
import okhttp3.mockwebserver.MockWebServer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link WebClientTest @WebClientTest} without Jackson.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@ClassPathExclusions("jackson-*.jar")
|
||||
@WebClientTest(ExampleWebClientService.class)
|
||||
@Import(MockWebServerConfiguration.class)
|
||||
class WebClientTestWithoutJacksonIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private MockWebServer server;
|
||||
|
||||
@Autowired
|
||||
private ExampleWebClientService client;
|
||||
|
||||
@Test
|
||||
void webClientTestCanBeUsedWhenJacksonIsNotOnTheClassPath() throws InterruptedException {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
assertThat(ClassUtils.isPresent("com.fasterxml.jackson.databind.Module", classLoader)).isFalse();
|
||||
assertThat(ClassUtils.isPresent("tools.jackson.databind.JacksonModule", classLoader)).isFalse();
|
||||
this.server.enqueue(new MockResponse().setBody("hello"));
|
||||
assertThat(this.client.test()).isEqualTo("hello");
|
||||
this.server.takeRequest();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2260,6 +2260,7 @@ bom {
|
||||
"spring-boot-validation",
|
||||
"spring-boot-web-server",
|
||||
"spring-boot-webclient",
|
||||
"spring-boot-webclient-test",
|
||||
"spring-boot-webflux",
|
||||
"spring-boot-webflux-test",
|
||||
"spring-boot-webmvc",
|
||||
|
||||
@@ -189,6 +189,7 @@ include "module:spring-boot-tx"
|
||||
include "module:spring-boot-validation"
|
||||
include "module:spring-boot-web-server"
|
||||
include "module:spring-boot-webclient"
|
||||
include "module:spring-boot-webclient-test"
|
||||
include "module:spring-boot-webflux"
|
||||
include "module:spring-boot-webflux-test"
|
||||
include "module:spring-boot-webmvc"
|
||||
|
||||
@@ -24,4 +24,6 @@ dependencies {
|
||||
api(project(":starter:spring-boot-starter-jackson-test"))
|
||||
api(project(":starter:spring-boot-starter-test"))
|
||||
api(project(":starter:spring-boot-starter-webclient"))
|
||||
|
||||
api(project(":module:spring-boot-webclient-test"))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user