diff --git a/spring-test/src/main/java/org/springframework/test/http/HttpMessageContentConverter.java b/spring-test/src/main/java/org/springframework/test/http/HttpMessageContentConverter.java index d11e8bf2d2c..0db0d441945 100644 --- a/spring-test/src/main/java/org/springframework/test/http/HttpMessageContentConverter.java +++ b/spring-test/src/main/java/org/springframework/test/http/HttpMessageContentConverter.java @@ -18,11 +18,13 @@ package org.springframework.test.http; import java.io.IOException; import java.lang.reflect.Type; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; import java.util.stream.StreamSupport; import org.springframework.core.ResolvableType; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpInputMessage; import org.springframework.http.MediaType; import org.springframework.http.converter.GenericHttpMessageConverter; @@ -31,6 +33,7 @@ import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.http.converter.SmartHttpMessageConverter; import org.springframework.mock.http.MockHttpInputMessage; import org.springframework.mock.http.MockHttpOutputMessage; +import org.springframework.test.json.JsonConverterDelegate; import org.springframework.util.Assert; import org.springframework.util.function.SingletonSupplier; @@ -39,8 +42,10 @@ import org.springframework.util.function.SingletonSupplier; * * @author Stephane Nicoll * @since 6.2 + * @deprecated in favor of static factory methods in {@link JsonConverterDelegate} */ -public class HttpMessageContentConverter { +@Deprecated(since = "7.0", forRemoval = true) +public class HttpMessageContentConverter implements JsonConverterDelegate { private static final MediaType JSON = MediaType.APPLICATION_JSON; @@ -69,6 +74,19 @@ public class HttpMessageContentConverter { } + @Override + public T read(String content, ResolvableType targetType) throws IOException{ + HttpInputMessage message = new MockHttpInputMessage(content.getBytes(StandardCharsets.UTF_8)); + message.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); + return convert(message, MediaType.APPLICATION_JSON, targetType); + } + + @Override + public T map(Object value, ResolvableType targetType) throws IOException { + return convertViaJson(value, targetType); + } + + /** * Convert the given {@link HttpInputMessage} whose content must match the * given {@link MediaType} to the requested {@code targetType}. diff --git a/spring-test/src/main/java/org/springframework/test/json/AbstractJsonContentAssert.java b/spring-test/src/main/java/org/springframework/test/json/AbstractJsonContentAssert.java index fe09defa168..27b2ea3b2fa 100644 --- a/spring-test/src/main/java/org/springframework/test/json/AbstractJsonContentAssert.java +++ b/spring-test/src/main/java/org/springframework/test/json/AbstractJsonContentAssert.java @@ -20,7 +20,6 @@ import java.io.File; import java.io.InputStream; import java.lang.reflect.Type; import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.function.Consumer; @@ -42,11 +41,6 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.Resource; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpInputMessage; -import org.springframework.http.MediaType; -import org.springframework.mock.http.MockHttpInputMessage; -import org.springframework.test.http.HttpMessageContentConverter; import org.springframework.util.Assert; /** @@ -77,7 +71,7 @@ public abstract class AbstractJsonContentAssert resourceLoadClass; @@ -92,7 +86,7 @@ public abstract class AbstractJsonContentAssert selfType) { super(actual, selfType); - this.contentConverter = (actual != null ? actual.getContentConverter() : null); + this.converterDelegate = (actual != null ? actual.getJsonConverterDelegate() : null); this.jsonLoader = new JsonLoader(null, null); as("JSON content"); } @@ -131,13 +125,12 @@ public abstract class AbstractJsonContentAssert T convertToTargetType(Type targetType) { String json = this.actual.getJson(); - if (this.contentConverter == null) { + if (this.converterDelegate == null) { throw new IllegalStateException( "No JSON message converter available to convert %s".formatted(json)); } try { - return this.contentConverter.convert(fromJson(json), MediaType.APPLICATION_JSON, - ResolvableType.forType(targetType)); + return this.converterDelegate.read(json, ResolvableType.forType(targetType)); } catch (Exception ex) { throw failure(new ValueProcessingFailed(json, @@ -146,12 +139,6 @@ public abstract class AbstractJsonContentAssert> valueRequirements) { Object value = new JsonPathValue(path).assertHasPath(); - JsonPathValueAssert valueAssert = new JsonPathValueAssert(value, path, this.contentConverter); + JsonPathValueAssert valueAssert = new JsonPathValueAssert(value, path, this.converterDelegate); valueRequirements.accept(() -> valueAssert); return this.myself; } diff --git a/spring-test/src/main/java/org/springframework/test/json/AbstractJsonValueAssert.java b/spring-test/src/main/java/org/springframework/test/json/AbstractJsonValueAssert.java index 5ce5fe0394f..d7ee9e58bd8 100644 --- a/spring-test/src/main/java/org/springframework/test/json/AbstractJsonValueAssert.java +++ b/spring-test/src/main/java/org/springframework/test/json/AbstractJsonValueAssert.java @@ -35,7 +35,6 @@ import org.jspecify.annotations.Nullable; import org.springframework.core.ResolvableType; import org.springframework.http.converter.GenericHttpMessageConverter; -import org.springframework.test.http.HttpMessageContentConverter; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -64,14 +63,23 @@ public abstract class AbstractJsonValueAssert selfType, - @Nullable HttpMessageContentConverter contentConverter) { + protected AbstractJsonValueAssert( + @Nullable Object actual, Class selfType, @Nullable JsonConverterDelegate converter) { super(actual, selfType); - this.contentConverter = contentConverter; + this.converterDelegate = converter; + } + + @SuppressWarnings("removal") + @Deprecated(since = "7.0", forRemoval = true) + protected AbstractJsonValueAssert( + @Nullable Object actual, Class selfType, + org.springframework.test.http.@Nullable HttpMessageContentConverter converter) { + + this(actual, selfType, (JsonConverterDelegate) converter); } @@ -196,12 +204,12 @@ public abstract class AbstractJsonValueAssert T convertToTargetType(Type targetType) { - if (this.contentConverter == null) { + if (this.converterDelegate == null) { throw new IllegalStateException( "No JSON message converter available to convert %s".formatted(actualToString())); } try { - return this.contentConverter.convertViaJson(this.actual, ResolvableType.forType(targetType)); + return this.converterDelegate.map(this.actual, ResolvableType.forType(targetType)); } catch (Exception ex) { throw valueProcessingFailed("To convert successfully to:%n %s%nBut it failed:%n %s%n" diff --git a/spring-test/src/main/java/org/springframework/test/json/DefaultJsonConverterDelegate.java b/spring-test/src/main/java/org/springframework/test/json/DefaultJsonConverterDelegate.java new file mode 100644 index 00000000000..f02973ed0a9 --- /dev/null +++ b/spring-test/src/main/java/org/springframework/test/json/DefaultJsonConverterDelegate.java @@ -0,0 +1,151 @@ +/* + * Copyright 2002-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.test.json; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.stream.StreamSupport; + +import org.springframework.core.ResolvableType; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.MediaType; +import org.springframework.http.converter.GenericHttpMessageConverter; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.http.converter.SmartHttpMessageConverter; +import org.springframework.mock.http.MockHttpInputMessage; +import org.springframework.mock.http.MockHttpOutputMessage; +import org.springframework.util.Assert; +import org.springframework.util.function.SingletonSupplier; + +/** + * Default {@link JsonConverterDelegate} based on {@link HttpMessageConverter}s. + * + * @author Stephane Nicoll + * @author Rossen Stoyanchev + * @since 7.0 + */ +final class DefaultJsonConverterDelegate implements JsonConverterDelegate { + + private static final MediaType JSON = MediaType.APPLICATION_JSON; + + private final List> messageConverters; + + + DefaultJsonConverterDelegate(Iterable> messageConverters) { + this.messageConverters = StreamSupport.stream(messageConverters.spliterator(), false).toList(); + Assert.notEmpty(this.messageConverters, "At least one message converter needs to be specified"); + } + + + @Override + public T read(String content, ResolvableType targetType) throws IOException{ + HttpInputMessage message = new MockHttpInputMessage(content.getBytes(StandardCharsets.UTF_8)); + message.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); + return read(message, MediaType.APPLICATION_JSON, targetType); + } + + /** + * Convert the given {@link HttpInputMessage} whose content must match the + * given {@link MediaType} to the requested {@code targetType}. + * @param message an input message + * @param mediaType the media type of the input + * @param targetType the target type + * @param the converted object type + * @return a value of the given {@code targetType} + */ + @SuppressWarnings("unchecked") + T read(HttpInputMessage message, MediaType mediaType, ResolvableType targetType) + throws IOException, HttpMessageNotReadableException { + + Class contextClass = targetType.getRawClass(); + SingletonSupplier javaType = SingletonSupplier.of(targetType::getType); + for (HttpMessageConverter messageConverter : this.messageConverters) { + if (messageConverter instanceof GenericHttpMessageConverter genericMessageConverter) { + Type type = javaType.obtain(); + if (genericMessageConverter.canRead(type, contextClass, mediaType)) { + return (T) genericMessageConverter.read(type, contextClass, message); + } + } + else if (messageConverter instanceof SmartHttpMessageConverter smartMessageConverter) { + if (smartMessageConverter.canRead(targetType, mediaType)) { + return (T) smartMessageConverter.read(targetType, message, null); + } + } + else { + Class targetClass = (contextClass != null ? contextClass : Object.class); + if (messageConverter.canRead(targetClass, mediaType)) { + HttpMessageConverter simpleMessageConverter = (HttpMessageConverter) messageConverter; + Class clazz = (Class) targetClass; + return simpleMessageConverter.read(clazz, message); + } + } + } + throw new IllegalStateException("No converter found to read [%s] to [%s]".formatted(mediaType, targetType)); + } + + /** + * Convert the given raw value to the given {@code targetType} by writing + * it first to JSON and reading it back. + * @param value the value to convert + * @param targetType the target type + * @param the converted object type + * @return a value of the given {@code targetType} + */ + @Override + public T map(Object value, ResolvableType targetType) throws IOException { + MockHttpOutputMessage outputMessage = writeToJson(value, ResolvableType.forInstance(value)); + return read(fromHttpOutputMessage(outputMessage), JSON, targetType); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private MockHttpOutputMessage writeToJson(Object value, ResolvableType valueType) throws IOException { + MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); + Class valueClass = value.getClass(); + SingletonSupplier javaType = SingletonSupplier.of(valueType::getType); + for (HttpMessageConverter messageConverter : this.messageConverters) { + if (messageConverter instanceof GenericHttpMessageConverter genericMessageConverter) { + Type type = javaType.obtain(); + if (genericMessageConverter.canWrite(type, valueClass, JSON)) { + genericMessageConverter.write(value, type, JSON, outputMessage); + return outputMessage; + } + } + else if (messageConverter instanceof SmartHttpMessageConverter smartMessageConverter) { + if (smartMessageConverter.canWrite(valueType, valueClass, JSON)) { + smartMessageConverter.write(value, valueType, JSON, outputMessage, null); + return outputMessage; + } + } + else if (messageConverter.canWrite(valueClass, JSON)) { + ((HttpMessageConverter) messageConverter).write(value, JSON, outputMessage); + return outputMessage; + } + } + throw new IllegalStateException("No converter found to convert [%s] to JSON".formatted(valueType)); + } + + private static HttpInputMessage fromHttpOutputMessage(MockHttpOutputMessage message) { + MockHttpInputMessage inputMessage = new MockHttpInputMessage(message.getBodyAsBytes()); + inputMessage.getHeaders().addAll(message.getHeaders()); + return inputMessage; + } + +} diff --git a/spring-test/src/main/java/org/springframework/test/json/JsonContent.java b/spring-test/src/main/java/org/springframework/test/json/JsonContent.java index b64c6604e3e..a18ec6a4f15 100644 --- a/spring-test/src/main/java/org/springframework/test/json/JsonContent.java +++ b/spring-test/src/main/java/org/springframework/test/json/JsonContent.java @@ -34,19 +34,32 @@ public final class JsonContent implements AssertProvider { private final String json; - private final @Nullable HttpMessageContentConverter contentConverter; + private final @Nullable JsonConverterDelegate converterDelegate; /** * Create a new {@code JsonContent} instance with the message converter to * use to deserialize content. * @param json the actual JSON content - * @param contentConverter the content converter to use + * @param converterDelegate the content converter to use */ - public JsonContent(String json, @Nullable HttpMessageContentConverter contentConverter) { + public JsonContent(String json, @Nullable JsonConverterDelegate converterDelegate) { Assert.notNull(json, "JSON must not be null"); this.json = json; - this.contentConverter = contentConverter; + this.converterDelegate = converterDelegate; + } + + /** + * Create a new {@code JsonContent} instance with the message converter to + * use to deserialize content. + * @param json the actual JSON content + * @param converter the content converter to use + * @deprecated in favour of {@link #JsonContent(String, JsonConverterDelegate)} + */ + @SuppressWarnings("removal") + @Deprecated(since = "7.0", forRemoval = true) + public JsonContent(String json, @Nullable HttpMessageContentConverter converter) { + this(json, (JsonConverterDelegate) converter); } /** @@ -54,7 +67,7 @@ public final class JsonContent implements AssertProvider { * @param json the actual JSON content */ public JsonContent(String json) { - this(json, null); + this(json, (JsonConverterDelegate) null); } @@ -74,11 +87,22 @@ public final class JsonContent implements AssertProvider { return this.json; } + /** + * Return the {@link JsonConverterDelegate} to use to decode JSON content. + * @since 7.0 + */ + public @Nullable JsonConverterDelegate getJsonConverterDelegate() { + return this.converterDelegate; + } + /** * Return the {@link HttpMessageContentConverter} to use to deserialize content. + * @deprecated in favour of {@link #getJsonConverterDelegate()} */ + @SuppressWarnings("removal") + @Deprecated(since = "7.0", forRemoval = true) @Nullable HttpMessageContentConverter getContentConverter() { - return this.contentConverter; + return (this.converterDelegate instanceof HttpMessageContentConverter cc ? cc : null); } @Override diff --git a/spring-test/src/main/java/org/springframework/test/json/JsonConverterDelegate.java b/spring-test/src/main/java/org/springframework/test/json/JsonConverterDelegate.java new file mode 100644 index 00000000000..016d274719a --- /dev/null +++ b/spring-test/src/main/java/org/springframework/test/json/JsonConverterDelegate.java @@ -0,0 +1,61 @@ +/* + * Copyright 2002-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.test.json; + +import java.io.IOException; + +import org.springframework.core.ResolvableType; +import org.springframework.http.converter.HttpMessageConverter; + +/** + * Delegate to abstract JSON type conversion in AssertJ support clases. + * + * @author Rossen Stoyanchev + * @since 7.0 + */ +public interface JsonConverterDelegate { + + /** + * Convert JSON content to the given {@code targetType}. + * @param content the JSON content + * @param targetType the target type + * @return the decoded object + * @param the target type + */ + T read(String content, ResolvableType targetType) throws IOException; + + /** + * Map the given Object value to the given {@code targetType}, via + * serialization and deserialization to and from JSON. This is useful for + * mapping generic maps and lists to higher level Objects. + * @param value the value to map + * @param targetType the target tyep + * @return the decoded object + * @param the target type + */ + T map(Object value, ResolvableType targetType) throws IOException; + + + /** + * Create a {@link JsonConverterDelegate} from message converters. + * @param candidates the candidates + */ + static JsonConverterDelegate of(Iterable> candidates) { + return new DefaultJsonConverterDelegate(candidates); + } + +} diff --git a/spring-test/src/main/java/org/springframework/test/json/JsonPathValueAssert.java b/spring-test/src/main/java/org/springframework/test/json/JsonPathValueAssert.java index 51d20fa06a2..48e44b78d98 100644 --- a/spring-test/src/main/java/org/springframework/test/json/JsonPathValueAssert.java +++ b/spring-test/src/main/java/org/springframework/test/json/JsonPathValueAssert.java @@ -19,8 +19,6 @@ package org.springframework.test.json; import com.jayway.jsonpath.JsonPath; import org.jspecify.annotations.Nullable; -import org.springframework.test.http.HttpMessageContentConverter; - /** * AssertJ {@linkplain org.assertj.core.api.Assert assertions} that can be applied * to a JSON value produced by evaluating a {@linkplain JsonPath JSON path} @@ -34,10 +32,8 @@ public class JsonPathValueAssert extends AbstractJsonValueAssert, ACTUAL> extends AbstractHttpServletResponseAssert { - private final @Nullable HttpMessageContentConverter contentConverter; + private final @Nullable JsonConverterDelegate converterDelegate; + protected AbstractMockHttpServletResponseAssert( - @Nullable HttpMessageContentConverter contentConverter, ACTUAL actual, Class selfType) { + @Nullable JsonConverterDelegate converterDelegate, ACTUAL actual, Class selfType) { super(actual, selfType); - this.contentConverter = contentConverter; + this.converterDelegate = converterDelegate; + } + + @SuppressWarnings("removal") + @Deprecated(since = "7.0", forRemoval = true) + protected AbstractMockHttpServletResponseAssert( + org.springframework.test.http.@Nullable HttpMessageContentConverter converter, + ACTUAL actual, Class selfType) { + + this((JsonConverterDelegate) converter, actual, selfType); } @@ -93,7 +103,7 @@ public abstract class AbstractMockHttpServletResponseAssert */ public AbstractJsonContentAssert bodyJson() { - return new JsonContentAssert(new JsonContent(readBody(), this.contentConverter)); + return new JsonContentAssert(new JsonContent(readBody(), this.converterDelegate)); } private String readBody() { diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/DefaultMvcTestResult.java b/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/DefaultMvcTestResult.java index a4adddbc3b1..5711e048037 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/DefaultMvcTestResult.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/DefaultMvcTestResult.java @@ -18,7 +18,7 @@ package org.springframework.test.web.servlet.assertj; import org.jspecify.annotations.Nullable; -import org.springframework.test.http.HttpMessageContentConverter; +import org.springframework.test.json.JsonConverterDelegate; import org.springframework.test.web.servlet.MvcResult; /** @@ -33,15 +33,15 @@ final class DefaultMvcTestResult implements MvcTestResult { private final @Nullable Exception unresolvedException; - private final @Nullable HttpMessageContentConverter contentConverter; + private final @Nullable JsonConverterDelegate converterDelegate; DefaultMvcTestResult(@Nullable MvcResult mvcResult, @Nullable Exception unresolvedException, - @Nullable HttpMessageContentConverter contentConverter) { + @Nullable JsonConverterDelegate converterDelegate) { this.mvcResult = mvcResult; this.unresolvedException = unresolvedException; - this.contentConverter = contentConverter; + this.converterDelegate = converterDelegate; } @@ -70,7 +70,7 @@ final class DefaultMvcTestResult implements MvcTestResult { */ @Override public MvcTestResultAssert assertThat() { - return new MvcTestResultAssert(this, this.contentConverter); + return new MvcTestResultAssert(this, this.converterDelegate); } } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MockMvcTester.java b/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MockMvcTester.java index 6d3a91a4f6c..c90719e8be4 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MockMvcTester.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MockMvcTester.java @@ -30,7 +30,7 @@ import org.springframework.http.HttpMethod; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockMultipartHttpServletRequest; -import org.springframework.test.http.HttpMessageContentConverter; +import org.springframework.test.json.JsonConverterDelegate; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.RequestBuilder; @@ -132,13 +132,13 @@ public final class MockMvcTester { private final MockMvc mockMvc; - private final @Nullable HttpMessageContentConverter contentConverter; + private final @Nullable JsonConverterDelegate converterDelegate; - private MockMvcTester(MockMvc mockMvc, @Nullable HttpMessageContentConverter contentConverter) { + private MockMvcTester(MockMvc mockMvc, @Nullable JsonConverterDelegate converter) { Assert.notNull(mockMvc, "mockMVC should not be null"); this.mockMvc = mockMvc; - this.contentConverter = contentConverter; + this.converterDelegate = converter; } /** @@ -232,7 +232,7 @@ public final class MockMvcTester { * @return a new instance using the specified converters */ public MockMvcTester withHttpMessageConverters(Iterable> httpMessageConverters) { - return new MockMvcTester(this.mockMvc, HttpMessageContentConverter.of(httpMessageConverters)); + return new MockMvcTester(this.mockMvc, JsonConverterDelegate.of(httpMessageConverters)); } /** @@ -374,10 +374,10 @@ public final class MockMvcTester { public MvcTestResult perform(RequestBuilder requestBuilder) { Object result = getMvcResultOrFailure(requestBuilder); if (result instanceof MvcResult mvcResult) { - return new DefaultMvcTestResult(mvcResult, null, this.contentConverter); + return new DefaultMvcTestResult(mvcResult, null, this.converterDelegate); } else { - return new DefaultMvcTestResult(null, (Exception) result, this.contentConverter); + return new DefaultMvcTestResult(null, (Exception) result, this.converterDelegate); } } @@ -483,7 +483,7 @@ public final class MockMvcTester { @Override public MvcTestResultAssert assertThat() { - return new MvcTestResultAssert(exchange(), MockMvcTester.this.contentConverter); + return new MvcTestResultAssert(exchange(), MockMvcTester.this.converterDelegate); } } @@ -541,7 +541,7 @@ public final class MockMvcTester { @Override public MvcTestResultAssert assertThat() { - return new MvcTestResultAssert(exchange(), MockMvcTester.this.contentConverter); + return new MvcTestResultAssert(exchange(), MockMvcTester.this.converterDelegate); } } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MvcTestResultAssert.java b/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MvcTestResultAssert.java index 8447205cddd..8d1866d18bd 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MvcTestResultAssert.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MvcTestResultAssert.java @@ -34,7 +34,7 @@ import org.jspecify.annotations.Nullable; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.test.http.HttpMessageContentConverter; +import org.springframework.test.json.JsonConverterDelegate; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.ResultHandler; import org.springframework.test.web.servlet.ResultMatcher; @@ -51,8 +51,8 @@ import org.springframework.web.servlet.ModelAndView; */ public class MvcTestResultAssert extends AbstractMockHttpServletResponseAssert { - MvcTestResultAssert(MvcTestResult actual, @Nullable HttpMessageContentConverter contentConverter) { - super(contentConverter, actual, MvcTestResultAssert.class); + MvcTestResultAssert(MvcTestResult actual, @Nullable JsonConverterDelegate converterDelegate) { + super(converterDelegate, actual, MvcTestResultAssert.class); } @Override diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java index 83fb0a28ff4..bf8f0517bad 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java @@ -39,10 +39,10 @@ import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.converter.HttpMessageConverters; -import org.springframework.test.http.HttpMessageContentConverter; import org.springframework.test.json.JsonAssert; import org.springframework.test.json.JsonComparator; import org.springframework.test.json.JsonCompareMode; +import org.springframework.test.json.JsonConverterDelegate; import org.springframework.test.util.AssertionErrors; import org.springframework.test.util.ExceptionCollector; import org.springframework.test.util.XmlExpectationsHelper; @@ -69,7 +69,7 @@ class DefaultRestTestClient implements RestTestClient { private final DefaultRestTestClientBuilder restTestClientBuilder; - private final @Nullable HttpMessageContentConverter messageContentConverter; + private final @Nullable JsonConverterDelegate converterDelegate; private final AtomicLong requestIndex = new AtomicLong(); @@ -81,7 +81,7 @@ class DefaultRestTestClient implements RestTestClient { this.restClient = builder.requestInterceptor(this.wiretapInterceptor).build(); this.entityResultConsumer = entityResultConsumer; this.restTestClientBuilder = restTestClientBuilder; - this.messageContentConverter = new ConverterCallback(this.restClient).getConverter(); + this.converterDelegate = new ConverterCallback(this.restClient).getConverter(); } @@ -138,20 +138,20 @@ class DefaultRestTestClient implements RestTestClient { private static class ConverterCallback { - private @Nullable HttpMessageContentConverter converter; + private @Nullable JsonConverterDelegate converter; ConverterCallback(RestClient client) { client.mutate() .configureMessageConverters(convertersBuilder -> { HttpMessageConverters converters = convertersBuilder.build(); if (converters.iterator().hasNext()) { - this.converter = HttpMessageContentConverter.of(converters); + this.converter = JsonConverterDelegate.of(converters); } }) .build(); } - public @Nullable HttpMessageContentConverter getConverter() { + public @Nullable JsonConverterDelegate getConverter() { return this.converter; } } @@ -290,7 +290,7 @@ class DefaultRestTestClient implements RestTestClient { (request, response) -> { byte[] requestBody = wiretapInterceptor.getRequestContent(this.requestId); return new ExchangeResult( - request, response, this.uriTemplate, requestBody, messageContentConverter); + request, response, this.uriTemplate, requestBody, converterDelegate); }, false), DefaultRestTestClient.this.entityResultConsumer); } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/ExchangeResult.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/ExchangeResult.java index c86b4d352ec..64d48530c7a 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/ExchangeResult.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/ExchangeResult.java @@ -38,7 +38,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.http.MediaType; import org.springframework.http.ResponseCookie; -import org.springframework.test.http.HttpMessageContentConverter; +import org.springframework.test.json.JsonConverterDelegate; import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -75,7 +75,7 @@ public class ExchangeResult { private final byte[] requestBody; - private final @Nullable HttpMessageContentConverter messageContentConverter; + private final @Nullable JsonConverterDelegate converterDelegate; /** Ensure single logging; for example, for expectAll. */ private boolean diagnosticsLogged; @@ -83,7 +83,7 @@ public class ExchangeResult { ExchangeResult( HttpRequest request, ConvertibleClientHttpResponse response, @Nullable String uriTemplate, - byte[] requestBody, @Nullable HttpMessageContentConverter messageContentConverter) { + byte[] requestBody, @Nullable JsonConverterDelegate converter) { Assert.notNull(request, "HttpRequest must not be null"); Assert.notNull(response, "ClientHttpResponse must not be null"); @@ -91,11 +91,11 @@ public class ExchangeResult { this.clientResponse = response; this.uriTemplate = uriTemplate; this.requestBody = requestBody; - this.messageContentConverter = messageContentConverter; + this.converterDelegate = converter; } ExchangeResult(ExchangeResult result) { - this(result.request, result.clientResponse, result.uriTemplate, result.requestBody, result.messageContentConverter); + this(result.request, result.clientResponse, result.uriTemplate, result.requestBody, result.converterDelegate); this.diagnosticsLogged = result.diagnosticsLogged; } @@ -202,11 +202,11 @@ public class ExchangeResult { } /** - * Return a content converter that delegates to the configured HTTP message converters. + * Return a {@link JsonConverterDelegate} based on the configured HTTP message converters. * Mainly for internal use from AssertJ support. */ - public @Nullable HttpMessageContentConverter getMessageContentConverter() { - return this.messageContentConverter; + public @Nullable JsonConverterDelegate getConverterDelegate() { + return this.converterDelegate; } /** diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/client/assertj/RestTestClientResponseAssert.java b/spring-test/src/main/java/org/springframework/test/web/servlet/client/assertj/RestTestClientResponseAssert.java index d69c49ecdc8..41c13174727 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/client/assertj/RestTestClientResponseAssert.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/client/assertj/RestTestClientResponseAssert.java @@ -342,7 +342,7 @@ public class RestTestClientResponseAssert * */ public AbstractJsonContentAssert bodyJson() { - return new JsonContentAssert(new JsonContent(readBody(), getExchangeResult().getMessageContentConverter())); + return new JsonContentAssert(new JsonContent(readBody(), getExchangeResult().getConverterDelegate())); } private String readBody() { diff --git a/spring-test/src/test/java/org/springframework/test/json/AbstractJsonContentAssertTests.java b/spring-test/src/test/java/org/springframework/test/json/AbstractJsonContentAssertTests.java index c37ea1914d5..3281c1b8ad8 100644 --- a/spring-test/src/test/java/org/springframework/test/json/AbstractJsonContentAssertTests.java +++ b/spring-test/src/test/java/org/springframework/test/json/AbstractJsonContentAssertTests.java @@ -53,7 +53,6 @@ import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.Resource; import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter; -import org.springframework.test.http.HttpMessageContentConverter; import org.springframework.util.FileCopyUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -85,8 +84,8 @@ class AbstractJsonContentAssertTests { private static final String DIFFERENT = loadJson("different.json"); - private static final HttpMessageContentConverter jsonContentConverter = HttpMessageContentConverter.of( - new JacksonJsonHttpMessageConverter(new JsonMapper())); + private static final JsonConverterDelegate jsonContentConverter = + JsonConverterDelegate.of(List.of(new JacksonJsonHttpMessageConverter(new JsonMapper()))); private static final JsonComparator comparator = JsonAssert.comparator(JsonCompareMode.LENIENT); @@ -120,10 +119,10 @@ class AbstractJsonContentAssertTests { .hasFamilyMember("Homer"); } - private AssertProvider> forJson(@Nullable String json, - @Nullable HttpMessageContentConverter jsonContentConverter) { + private AssertProvider> forJson( + @Nullable String json, @Nullable JsonConverterDelegate converter) { - return () -> new TestJsonContentAssert(json, jsonContentConverter); + return () -> new TestJsonContentAssert(json, converter); } private static class FamilyAssertFactory extends InstanceOfAssertFactory { @@ -386,8 +385,8 @@ class AbstractJsonContentAssertTests { return () -> new TestJsonContentAssert(json, null); } - private AssertProvider> forJson(@Nullable String json, HttpMessageContentConverter jsonContentConverter) { - return () -> new TestJsonContentAssert(json, jsonContentConverter); + private AssertProvider> forJson(@Nullable String json, JsonConverterDelegate converter) { + return () -> new TestJsonContentAssert(json, converter); } } @@ -886,8 +885,8 @@ class AbstractJsonContentAssertTests { private static class TestJsonContentAssert extends AbstractJsonContentAssert { - public TestJsonContentAssert(@Nullable String json, @Nullable HttpMessageContentConverter jsonContentConverter) { - super((json != null ? new JsonContent(json, jsonContentConverter) : null), TestJsonContentAssert.class); + public TestJsonContentAssert(@Nullable String json, @Nullable JsonConverterDelegate converter) { + super((json != null ? new JsonContent(json, converter) : null), TestJsonContentAssert.class); } } diff --git a/spring-test/src/test/java/org/springframework/test/http/HttpMessageContentConverterTests.java b/spring-test/src/test/java/org/springframework/test/json/DefaultJsonConverterDelegateTests.java similarity index 81% rename from spring-test/src/test/java/org/springframework/test/http/HttpMessageContentConverterTests.java rename to spring-test/src/test/java/org/springframework/test/json/DefaultJsonConverterDelegateTests.java index 87b5986bc1c..b394ab955a2 100644 --- a/spring-test/src/test/java/org/springframework/test/http/HttpMessageContentConverterTests.java +++ b/spring-test/src/test/java/org/springframework/test/json/DefaultJsonConverterDelegateTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.test.http; +package org.springframework.test.json; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -46,11 +46,11 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; /** - * Tests for {@link HttpMessageContentConverter}. + * Tests for {@link DefaultJsonConverterDelegate}. * * @author Stephane Nicoll */ -class HttpMessageContentConverterTests { +class DefaultJsonConverterDelegateTests { private static final MediaType JSON = MediaType.APPLICATION_JSON; @@ -58,17 +58,18 @@ class HttpMessageContentConverterTests { private static final JacksonJsonHttpMessageConverter jacksonMessageConverter = new JacksonJsonHttpMessageConverter(); + @Test void createInstanceWithEmptyIterable() { assertThatIllegalArgumentException() - .isThrownBy(() -> HttpMessageContentConverter.of(List.of())) + .isThrownBy(() -> new DefaultJsonConverterDelegate(List.of())) .withMessage("At least one message converter needs to be specified"); } @Test void createInstanceWithEmptyVarArg() { assertThatIllegalArgumentException() - .isThrownBy(HttpMessageContentConverter::of) + .isThrownBy(() -> new DefaultJsonConverterDelegate(List.of())) .withMessage("At least one message converter needs to be specified"); } @@ -79,9 +80,9 @@ class HttpMessageContentConverterTests { listOfIntegers, JSON, message, List.of(1, 2, 3)); SmartHttpMessageConverter secondConverter = mockSmartConverterForRead( listOfIntegers, JSON, message, List.of(3, 2, 1)); - HttpMessageContentConverter contentConverter = HttpMessageContentConverter.of( - List.of(firstConverter, secondConverter)); - List data = contentConverter.convert(message, JSON, listOfIntegers); + DefaultJsonConverterDelegate converter = + new DefaultJsonConverterDelegate(List.of(firstConverter, secondConverter)); + List data = converter.read(message, JSON, listOfIntegers); assertThat(data).containsExactly(1, 2, 3); verify(firstConverter).canRead(listOfIntegers, JSON); verifyNoInteractions(secondConverter); @@ -90,9 +91,9 @@ class HttpMessageContentConverterTests { @Test void convertInvokesGenericHttpMessageConverter() throws IOException { GenericHttpMessageConverter firstConverter = mock(GenericHttpMessageConverter.class); - HttpMessageContentConverter contentConverter = HttpMessageContentConverter.of( - List.of(firstConverter, jacksonMessageConverter)); - List data = contentConverter.convert(createMessage("[2,3,4]"), JSON, listOfIntegers); + DefaultJsonConverterDelegate converter = + new DefaultJsonConverterDelegate(List.of(firstConverter, jacksonMessageConverter)); + List data = converter.read(createMessage("[2,3,4]"), JSON, listOfIntegers); assertThat(data).containsExactly(2, 3, 4); verify(firstConverter).canRead(listOfIntegers.getType(), List.class, JSON); } @@ -103,9 +104,9 @@ class HttpMessageContentConverterTests { GenericHttpMessageConverter firstConverter = mock(GenericHttpMessageConverter.class); SmartHttpMessageConverter smartConverter = mockSmartConverterForRead( listOfIntegers, JSON, message, List.of(1, 2, 3)); - HttpMessageContentConverter contentConverter = HttpMessageContentConverter.of( - List.of(firstConverter, smartConverter)); - List data = contentConverter.convert(message, JSON, listOfIntegers); + DefaultJsonConverterDelegate converter = + new DefaultJsonConverterDelegate(List.of(firstConverter, smartConverter)); + List data = converter.read(message, JSON, listOfIntegers); assertThat(data).containsExactly(1, 2, 3); verify(smartConverter).canRead(listOfIntegers, JSON); } @@ -117,9 +118,9 @@ class HttpMessageContentConverterTests { listOfIntegers, JSON, message, List.of(1, 2, 3)); HttpMessageConverter thirdConverter = mockSimpleConverterForRead( List.class, MediaType.TEXT_PLAIN, message, List.of(1, 2, 3)); - HttpMessageContentConverter contentConverter = HttpMessageContentConverter.of( - List.of(jacksonMessageConverter, secondConverter, thirdConverter)); - List data = contentConverter.convert(message, MediaType.TEXT_PLAIN, listOfIntegers); + DefaultJsonConverterDelegate converter = + new DefaultJsonConverterDelegate(List.of(jacksonMessageConverter, secondConverter, thirdConverter)); + List data = converter.read(message, MediaType.TEXT_PLAIN, listOfIntegers); assertThat(data).containsExactly(1, 2, 3); verify(secondConverter).canRead(listOfIntegers, MediaType.TEXT_PLAIN); verify(thirdConverter).canRead(List.class, MediaType.TEXT_PLAIN); @@ -132,10 +133,9 @@ class HttpMessageContentConverterTests { listOfIntegers, MediaType.TEXT_PLAIN, message, List.of(1, 2, 3)); SmartHttpMessageConverter htmlConverter = mockSmartConverterForRead( listOfIntegers, MediaType.TEXT_HTML, message, List.of(3, 2, 1)); - HttpMessageContentConverter contentConverter = HttpMessageContentConverter.of( - List.of(textConverter, htmlConverter)); + DefaultJsonConverterDelegate converter = new DefaultJsonConverterDelegate(List.of(textConverter, htmlConverter)); assertThatIllegalStateException() - .isThrownBy(() -> contentConverter.convert(message, JSON, listOfIntegers)) + .isThrownBy(() -> converter.read(message, JSON, listOfIntegers)) .withMessage("No converter found to read [application/json] to [java.util.List]"); verify(textConverter).canRead(listOfIntegers, JSON); verify(htmlConverter).canRead(listOfIntegers, JSON); @@ -148,9 +148,9 @@ class HttpMessageContentConverterTests { SmartHttpMessageConverter readConverter = mockSmartConverterForRead(listOfIntegers, JSON, null, List.of(1, 2, 3)); SmartHttpMessageConverter firstWriteJsonConverter = mockSmartConverterForWritingJson(value, valueType, "[1,2,3]"); SmartHttpMessageConverter secondWriteJsonConverter = mockSmartConverterForWritingJson(value, valueType, "[3,2,1]"); - HttpMessageContentConverter contentConverter = HttpMessageContentConverter.of( - List.of(readConverter, firstWriteJsonConverter, secondWriteJsonConverter)); - List data = contentConverter.convertViaJson(value, listOfIntegers); + JsonConverterDelegate converter = + new DefaultJsonConverterDelegate(List.of(readConverter, firstWriteJsonConverter, secondWriteJsonConverter)); + List data = converter.map(value, listOfIntegers); assertThat(data).containsExactly(1, 2, 3); verify(readConverter).canRead(listOfIntegers, JSON); verify(firstWriteJsonConverter).canWrite(valueType, String.class, JSON); @@ -163,9 +163,9 @@ class HttpMessageContentConverterTests { ResolvableType valueType = ResolvableType.forInstance(value); SmartHttpMessageConverter readConverter = mockSmartConverterForRead(listOfIntegers, JSON, null, List.of(1, 2, 3)); GenericHttpMessageConverter writeConverter = mockGenericConverterForWritingJson(value, valueType, "[3,2,1]"); - HttpMessageContentConverter contentConverter = HttpMessageContentConverter.of( - List.of(readConverter, writeConverter, jacksonMessageConverter)); - List data = contentConverter.convertViaJson("[1, 2, 3]", listOfIntegers); + JsonConverterDelegate converter = + new DefaultJsonConverterDelegate(List.of(readConverter, writeConverter, jacksonMessageConverter)); + List data = converter.map("[1, 2, 3]", listOfIntegers); assertThat(data).containsExactly(1, 2, 3); verify(readConverter).canRead(listOfIntegers, JSON); verify(writeConverter).canWrite(valueType.getType(), value.getClass(), JSON); @@ -177,9 +177,9 @@ class HttpMessageContentConverterTests { ResolvableType valueType = ResolvableType.forInstance(value); SmartHttpMessageConverter readConverter = mockSmartConverterForRead(listOfIntegers, JSON, null, List.of(1, 2, 3)); SmartHttpMessageConverter writeConverter = mockSmartConverterForWritingJson(value, valueType, "[3,2,1]"); - HttpMessageContentConverter contentConverter = HttpMessageContentConverter.of( - List.of(readConverter, writeConverter, jacksonMessageConverter)); - List data = contentConverter.convertViaJson("[1, 2, 3]", listOfIntegers); + JsonConverterDelegate converter = + new DefaultJsonConverterDelegate(List.of(readConverter, writeConverter, jacksonMessageConverter)); + List data = converter.map("[1, 2, 3]", listOfIntegers); assertThat(data).containsExactly(1, 2, 3); verify(readConverter).canRead(listOfIntegers, JSON); verify(writeConverter).canWrite(valueType, value.getClass(), JSON); @@ -190,9 +190,9 @@ class HttpMessageContentConverterTests { String value = "1,2,3"; SmartHttpMessageConverter readConverter = mockSmartConverterForRead(listOfIntegers, JSON, null, List.of(1, 2, 3)); HttpMessageConverter writeConverter = mockSimpleConverterForWritingJson(value, "[3,2,1]"); - HttpMessageContentConverter contentConverter = HttpMessageContentConverter.of( - List.of(readConverter, writeConverter, jacksonMessageConverter)); - List data = contentConverter.convertViaJson("[1, 2, 3]", listOfIntegers); + JsonConverterDelegate converterDelegate = + new DefaultJsonConverterDelegate(List.of(readConverter, writeConverter, jacksonMessageConverter)); + List data = converterDelegate.map("[1, 2, 3]", listOfIntegers); assertThat(data).containsExactly(1, 2, 3); verify(readConverter).canRead(listOfIntegers, JSON); verify(writeConverter).canWrite(value.getClass(), JSON); @@ -203,9 +203,9 @@ class HttpMessageContentConverterTests { String value = "1,2,3"; ResolvableType valueType = ResolvableType.forInstance(value); SmartHttpMessageConverter readConverter = mockSmartConverterForRead(listOfIntegers, JSON, null, List.of(1, 2, 3)); - HttpMessageContentConverter contentConverter = HttpMessageContentConverter.of(List.of(readConverter)); + JsonConverterDelegate converter = new DefaultJsonConverterDelegate(List.of(readConverter)); assertThatIllegalStateException() - .isThrownBy(() -> contentConverter.convertViaJson(value, listOfIntegers)) + .isThrownBy(() -> converter.map(value, listOfIntegers)) .withMessage("No converter found to convert [java.lang.String] to JSON"); verify(readConverter).canWrite(valueType, value.getClass(), JSON); } diff --git a/spring-test/src/test/java/org/springframework/test/json/JsonContentTests.java b/spring-test/src/test/java/org/springframework/test/json/JsonContentTests.java index 3f698473560..e8f1ebaa92a 100644 --- a/spring-test/src/test/java/org/springframework/test/json/JsonContentTests.java +++ b/spring-test/src/test/java/org/springframework/test/json/JsonContentTests.java @@ -16,10 +16,11 @@ package org.springframework.test.json; +import java.util.List; + import org.junit.jupiter.api.Test; import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.test.http.HttpMessageContentConverter; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -63,9 +64,9 @@ class JsonContentTests { @Test void getJsonContentConverterShouldReturnConverter() { - HttpMessageContentConverter contentConverter = HttpMessageContentConverter.of(mock(HttpMessageConverter.class)); - JsonContent content = new JsonContent(JSON, contentConverter); - assertThat(content.getContentConverter()).isSameAs(contentConverter); + JsonConverterDelegate converter = JsonConverterDelegate.of(List.of(mock(HttpMessageConverter.class))); + JsonContent content = new JsonContent(JSON, converter); + assertThat(content.getJsonConverterDelegate()).isSameAs(converter); } } diff --git a/spring-test/src/test/java/org/springframework/test/json/JsonPathValueAssertTests.java b/spring-test/src/test/java/org/springframework/test/json/JsonPathValueAssertTests.java index 1c26fa1865e..f760a619a37 100644 --- a/spring-test/src/test/java/org/springframework/test/json/JsonPathValueAssertTests.java +++ b/spring-test/src/test/java/org/springframework/test/json/JsonPathValueAssertTests.java @@ -30,7 +30,6 @@ import org.junit.jupiter.api.Test; import tools.jackson.databind.json.JsonMapper; import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter; -import org.springframework.test.http.HttpMessageContentConverter; import org.springframework.util.StringUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -205,8 +204,8 @@ class JsonPathValueAssertTests { @Nested class ConvertToTests { - private static final HttpMessageContentConverter jsonContentConverter = HttpMessageContentConverter.of( - new JacksonJsonHttpMessageConverter(new JsonMapper())); + private static final JsonConverterDelegate jsonContentConverter = + JsonConverterDelegate.of(List.of(new JacksonJsonHttpMessageConverter(new JsonMapper()))); @Test void convertToWithoutHttpMessageConverter() { diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AbstractMockHttpServletResponseAssertTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AbstractMockHttpServletResponseAssertTests.java index cefeb2b7343..9ffa1c23d39 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AbstractMockHttpServletResponseAssertTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AbstractMockHttpServletResponseAssertTests.java @@ -25,6 +25,7 @@ import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.test.json.JsonContent; +import org.springframework.test.json.JsonConverterDelegate; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -138,7 +139,7 @@ public class AbstractMockHttpServletResponseAssertTests { private static final class ResponseAssert extends AbstractMockHttpServletResponseAssert { ResponseAssert(MockHttpServletResponse actual) { - super(null, actual, ResponseAssert.class); + super((JsonConverterDelegate) null, actual, ResponseAssert.class); } @Override