diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
index 725b8c1148..2748a3ff98 100644
--- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
+++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
@@ -5998,9 +5998,9 @@ A list of the auto-configuration that is enabled by `@JsonTest` can be
==== Auto-configured Spring MVC Tests
To test Spring MVC controllers are working as expected, you can use the `@WebMvcTest`
annotation. `@WebMvcTest` auto-configures the Spring MVC infrastructure and limits
-scanned beans to `@Controller`, `@ControllerAdvice`, `@JsonComponent`, `Filter`,
-`WebMvcConfigurer`, and `HandlerMethodArgumentResolver`. Regular `@Component` beans
-are not scanned when using this annotation.
+scanned beans to `@Controller`, `@ControllerAdvice`, `@JsonComponent`, `@Converter`,
+`Filter`, `WebMvcConfigurer`, and `HandlerMethodArgumentResolver`. Regular `@Component`
+beans are not scanned when using this annotation.
Often, `@WebMvcTest` is limited to a single controller and is used in combination with
`@MockBean` to provide mock implementations for required collaborators.
@@ -6102,8 +6102,8 @@ A list of the auto-configuration settings that are enabled by `@WebMvcTest` can
To test that Spring WebFlux controllers are working as expected, you can use the
`@WebFluxTest` annotation. `@WebFluxTest` auto-configures the Spring WebFlux
infrastructure and limits scanned beans to `@Controller`, `@ControllerAdvice`,
-`@JsonComponent`, and `WebFluxConfigurer`. Regular `@Component` beans are not scanned
-when the `@WebFluxTest` annotation is used.
+`@JsonComponent`, `Converter`, and `WebFluxConfigurer`. Regular `@Component` beans are
+not scanned when the `@WebFluxTest` annotation is used.
Often, `@WebFluxTest` is limited to a single controller and used in combination with the
`@MockBean` annotation to provide mock implementations for required collaborators.
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTest.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTest.java
index bd174d0a42..888612db3f 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTest.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTest.java
@@ -43,8 +43,9 @@ import org.springframework.test.web.reactive.server.WebTestClient;
*
* Using this annotation will disable full auto-configuration and instead apply only
* configuration relevant to WebFlux tests (i.e. {@code @Controller},
- * {@code @ControllerAdvice}, {@code @JsonComponent} and {@code WebFluxConfigurer} beans
- * but not {@code @Component}, {@code @Service} or {@code @Repository} beans).
+ * {@code @ControllerAdvice}, {@code @JsonComponent}, {@code Converter}, and
+ * {@code WebFluxConfigurer} beans but not {@code @Component}, {@code @Service} or
+ * {@code @Repository} beans).
*
* By default, tests annotated with {@code @WebFluxTest} will also auto-configure a
* {@link WebTestClient}. For more fine-grained control of WebTestClient the
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTypeExcludeFilter.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTypeExcludeFilter.java
index 5acf738fd7..cf9666844c 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTypeExcludeFilter.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/reactive/WebFluxTypeExcludeFilter.java
@@ -26,6 +26,8 @@ import org.springframework.boot.jackson.JsonComponent;
import org.springframework.boot.test.autoconfigure.filter.AnnotationCustomizableTypeExcludeFilter;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.stereotype.Controller;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
@@ -45,6 +47,8 @@ class WebFluxTypeExcludeFilter extends AnnotationCustomizableTypeExcludeFilter {
includes.add(ControllerAdvice.class);
includes.add(JsonComponent.class);
includes.add(WebFluxConfigurer.class);
+ includes.add(Converter.class);
+ includes.add(GenericConverter.class);
DEFAULT_INCLUDES = Collections.unmodifiableSet(includes);
}
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTest.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTest.java
index ae112d6b18..0ef95d4de8 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTest.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTest.java
@@ -43,7 +43,7 @@ import org.springframework.test.web.servlet.MockMvc;
*
* Using this annotation will disable full auto-configuration and instead apply only
* configuration relevant to MVC tests (i.e. {@code @Controller},
- * {@code @ControllerAdvice}, {@code @JsonComponent} {@code Filter},
+ * {@code @ControllerAdvice}, {@code @JsonComponent}, {@code Converter}, {@code Filter},
* {@code WebMvcConfigurer} and {@code HandlerMethodArgumentResolver} beans but not
* {@code @Component}, {@code @Service} or {@code @Repository} beans).
*
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTypeExcludeFilter.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTypeExcludeFilter.java
index 037ac1bf63..f8cda83e81 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTypeExcludeFilter.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTypeExcludeFilter.java
@@ -29,6 +29,8 @@ import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.stereotype.Controller;
import org.springframework.util.ObjectUtils;
@@ -56,6 +58,8 @@ class WebMvcTypeExcludeFilter extends AnnotationCustomizableTypeExcludeFilter {
includes.add(HandlerMethodArgumentResolver.class);
includes.add(HttpMessageConverter.class);
includes.add(ErrorAttributes.class);
+ includes.add(Converter.class);
+ includes.add(GenericConverter.class);
DEFAULT_INCLUDES = Collections.unmodifiableSet(includes);
}
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleController2.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleController2.java
index 99b85e786b..e31952a97d 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleController2.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleController2.java
@@ -21,6 +21,7 @@ import reactor.core.publisher.Mono;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
/**
@@ -36,4 +37,9 @@ public class ExampleController2 {
return Mono.just("two");
}
+ @GetMapping("/two/{id}")
+ public Mono one(@PathVariable ExampleId id) {
+ return Mono.just(id.getId() + "two");
+ }
+
}
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleId.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleId.java
new file mode 100644
index 0000000000..c56a5d6c3c
--- /dev/null
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleId.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive.webclient;
+
+import java.util.UUID;
+
+import org.springframework.core.convert.converter.Converter;
+
+/**
+ * An example attribute that requires a {@link Converter}.
+ *
+ * @author Stephane Nicoll
+ */
+public class ExampleId {
+
+ private final UUID id;
+
+ ExampleId(UUID id) {
+ this.id = id;
+ }
+
+ public UUID getId() {
+ return this.id;
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleIdConverter.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleIdConverter.java
new file mode 100644
index 0000000000..dc4b2670af
--- /dev/null
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/ExampleIdConverter.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive.webclient;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.UUID;
+
+import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
+import org.springframework.core.convert.TypeDescriptor;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.core.convert.converter.GenericConverter;
+import org.springframework.lang.Nullable;
+import org.springframework.stereotype.Component;
+
+/**
+ * Example {@link Converter} used with {@link WebFluxTest} tests.
+ *
+ * @author Stephane Nicoll
+ */
+@Component
+public class ExampleIdConverter implements GenericConverter {
+
+ @Override
+ public Set getConvertibleTypes() {
+ return Collections.singleton(new ConvertiblePair(String.class, ExampleId.class));
+ }
+
+ @Nullable
+ @Override
+ public Object convert(@Nullable Object source, TypeDescriptor sourceType,
+ TypeDescriptor targetType) {
+ if (source == null) {
+ return null;
+ }
+ return new ExampleId(UUID.fromString((String) source));
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/WebFluxTestConverterIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/WebFluxTestConverterIntegrationTests.java
new file mode 100644
index 0000000000..718e19adf7
--- /dev/null
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/WebFluxTestConverterIntegrationTests.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.reactive.webclient;
+
+import java.util.UUID;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+/**
+ * Tests for {@link WebFluxTest} to validate converters are discovered.
+ *
+ * @author Stephane Nicoll
+ */
+@RunWith(SpringRunner.class)
+@WebFluxTest(controllers = ExampleController2.class)
+public class WebFluxTestConverterIntegrationTests {
+
+ @Autowired
+ private WebTestClient webClient;
+
+ @Test
+ public void shouldFindConverter() {
+ UUID id = UUID.randomUUID();
+ this.webClient.get().uri("/two/" + id).exchange().expectStatus().isOk()
+ .expectBody(String.class).isEqualTo(id + "two");
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleController2.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleController2.java
index de719422b3..c33684330b 100644
--- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleController2.java
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleController2.java
@@ -19,6 +19,7 @@ package org.springframework.boot.test.autoconfigure.web.servlet.mockmvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;
/**
@@ -35,4 +36,10 @@ public class ExampleController2 {
return argument + "two";
}
+ @GetMapping("/two/{id}")
+ @ResponseBody
+ public String one(@PathVariable ExampleId id) {
+ return id.getId() + "two";
+ }
+
}
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleId.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleId.java
new file mode 100644
index 0000000000..c054ebe1bf
--- /dev/null
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleId.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.servlet.mockmvc;
+
+import java.util.UUID;
+
+import org.springframework.core.convert.converter.Converter;
+
+/**
+ * An example attribute that requires a {@link Converter}.
+ *
+ * @author Stephane Nicoll
+ */
+public class ExampleId {
+
+ private final UUID id;
+
+ ExampleId(UUID id) {
+ this.id = id;
+ }
+
+ public UUID getId() {
+ return this.id;
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleIdConverter.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleIdConverter.java
new file mode 100644
index 0000000000..54de1f3c7d
--- /dev/null
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/ExampleIdConverter.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.servlet.mockmvc;
+
+import java.util.UUID;
+
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.stereotype.Component;
+
+/**
+ * Example {@link Converter} used with {@link WebMvcTest} tests.
+ *
+ * @author Stephane Nicoll
+ */
+@Component
+public class ExampleIdConverter implements Converter {
+
+ @Override
+ public ExampleId convert(String source) {
+ return new ExampleId(UUID.fromString(source));
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestConverterIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestConverterIntegrationTests.java
new file mode 100644
index 0000000000..759782d759
--- /dev/null
+++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestConverterIntegrationTests.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012-2017 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
+ *
+ * http://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.test.autoconfigure.web.servlet.mockmvc;
+
+import java.util.UUID;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+/**
+ * Tests for {@link WebMvcTest} to validate converters are discovered.
+ *
+ * @author Stephane Nicoll
+ */
+@RunWith(SpringRunner.class)
+@WebMvcTest(controllers = ExampleController2.class, secure = false)
+public class WebMvcTestConverterIntegrationTests {
+
+ @Autowired
+ private MockMvc mvc;
+
+ @Test
+ public void shouldFindConverter() throws Exception {
+ String id = UUID.randomUUID().toString();
+ this.mvc.perform(get("/two/" + id)).andExpect(content().string(id + "two"))
+ .andExpect(status().isOk());
+ }
+
+}