Browse Source

Add JsonConverterDelegate

The JsonConverterDelegate interface replaces usages of
HttpMessageContentConverter to provides the flexibility to use either
message converters or WebFlux codecs.

HttpMessageContentConverter is deprecated, and replaced with a package
private copy (DefaultJsonConverterDelegate) in the
org.springframework.test.json package that is accessible through
a static method on JsonConverterDelegate.

See gh-35737
pull/35768/head
rstoyanchev 2 months ago
parent
commit
125002844e
  1. 20
      spring-test/src/main/java/org/springframework/test/http/HttpMessageContentConverter.java
  2. 25
      spring-test/src/main/java/org/springframework/test/json/AbstractJsonContentAssert.java
  3. 22
      spring-test/src/main/java/org/springframework/test/json/AbstractJsonValueAssert.java
  4. 151
      spring-test/src/main/java/org/springframework/test/json/DefaultJsonConverterDelegate.java
  5. 36
      spring-test/src/main/java/org/springframework/test/json/JsonContent.java
  6. 61
      spring-test/src/main/java/org/springframework/test/json/JsonConverterDelegate.java
  7. 8
      spring-test/src/main/java/org/springframework/test/json/JsonPathValueAssert.java
  8. 20
      spring-test/src/main/java/org/springframework/test/web/servlet/assertj/AbstractMockHttpServletResponseAssert.java
  9. 10
      spring-test/src/main/java/org/springframework/test/web/servlet/assertj/DefaultMvcTestResult.java
  10. 18
      spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MockMvcTester.java
  11. 6
      spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MvcTestResultAssert.java
  12. 14
      spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java
  13. 16
      spring-test/src/main/java/org/springframework/test/web/servlet/client/ExchangeResult.java
  14. 2
      spring-test/src/main/java/org/springframework/test/web/servlet/client/assertj/RestTestClientResponseAssert.java
  15. 19
      spring-test/src/test/java/org/springframework/test/json/AbstractJsonContentAssertTests.java
  16. 68
      spring-test/src/test/java/org/springframework/test/json/DefaultJsonConverterDelegateTests.java
  17. 9
      spring-test/src/test/java/org/springframework/test/json/JsonContentTests.java
  18. 5
      spring-test/src/test/java/org/springframework/test/json/JsonPathValueAssertTests.java
  19. 3
      spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AbstractMockHttpServletResponseAssertTests.java

20
spring-test/src/main/java/org/springframework/test/http/HttpMessageContentConverter.java

@ -18,11 +18,13 @@ package org.springframework.test.http; @@ -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; @@ -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; @@ -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 { @@ -69,6 +74,19 @@ public class HttpMessageContentConverter {
}
@Override
public <T> 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> 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}.

25
spring-test/src/main/java/org/springframework/test/json/AbstractJsonContentAssert.java

@ -20,7 +20,6 @@ import java.io.File; @@ -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; @@ -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<SELF extends AbstractJsonContent @@ -77,7 +71,7 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent
private static final Failures failures = Failures.instance();
private final @Nullable HttpMessageContentConverter contentConverter;
private final @Nullable JsonConverterDelegate converterDelegate;
private @Nullable Class<?> resourceLoadClass;
@ -92,7 +86,7 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent @@ -92,7 +86,7 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent
*/
protected AbstractJsonContentAssert(@Nullable JsonContent actual, Class<?> 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<SELF extends AbstractJsonContent @@ -131,13 +125,12 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent
private <T> 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<SELF extends AbstractJsonContent @@ -146,12 +139,6 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent
}
}
private HttpInputMessage fromJson(String json) {
MockHttpInputMessage inputMessage = new MockHttpInputMessage(json.getBytes(StandardCharsets.UTF_8));
inputMessage.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
return inputMessage;
}
// JsonPath support
@ -163,7 +150,7 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent @@ -163,7 +150,7 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent
*/
public JsonPathValueAssert extractingPath(String path) {
Object value = new JsonPathValue(path).getValue();
return new JsonPathValueAssert(value, path, this.contentConverter);
return new JsonPathValueAssert(value, path, this.converterDelegate);
}
/**
@ -174,7 +161,7 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent @@ -174,7 +161,7 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent
*/
public SELF hasPathSatisfying(String path, Consumer<AssertProvider<JsonPathValueAssert>> 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;
}

22
spring-test/src/main/java/org/springframework/test/json/AbstractJsonValueAssert.java

@ -35,7 +35,6 @@ import org.jspecify.annotations.Nullable; @@ -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<SELF extends AbstractJsonValueAsse @@ -64,14 +63,23 @@ public abstract class AbstractJsonValueAssert<SELF extends AbstractJsonValueAsse
private final Failures failures = Failures.instance();
private final @Nullable HttpMessageContentConverter contentConverter;
private final @Nullable JsonConverterDelegate converterDelegate;
protected AbstractJsonValueAssert(@Nullable Object actual, Class<?> 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<SELF extends AbstractJsonValueAsse @@ -196,12 +204,12 @@ public abstract class AbstractJsonValueAssert<SELF extends AbstractJsonValueAsse
}
private <T> 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"

151
spring-test/src/main/java/org/springframework/test/json/DefaultJsonConverterDelegate.java

@ -0,0 +1,151 @@ @@ -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<HttpMessageConverter<?>> messageConverters;
DefaultJsonConverterDelegate(Iterable<HttpMessageConverter<?>> 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> 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 <T> the converted object type
* @return a value of the given {@code targetType}
*/
@SuppressWarnings("unchecked")
<T> T read(HttpInputMessage message, MediaType mediaType, ResolvableType targetType)
throws IOException, HttpMessageNotReadableException {
Class<?> contextClass = targetType.getRawClass();
SingletonSupplier<Type> 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<T> simpleMessageConverter = (HttpMessageConverter<T>) messageConverter;
Class<? extends T> clazz = (Class<? extends T>) 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 <T> the converted object type
* @return a value of the given {@code targetType}
*/
@Override
public <T> 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<Type> 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<Object>) 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;
}
}

36
spring-test/src/main/java/org/springframework/test/json/JsonContent.java

@ -34,19 +34,32 @@ public final class JsonContent implements AssertProvider<JsonContentAssert> { @@ -34,19 +34,32 @@ public final class JsonContent implements AssertProvider<JsonContentAssert> {
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<JsonContentAssert> { @@ -54,7 +67,7 @@ public final class JsonContent implements AssertProvider<JsonContentAssert> {
* @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<JsonContentAssert> { @@ -74,11 +87,22 @@ public final class JsonContent implements AssertProvider<JsonContentAssert> {
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

61
spring-test/src/main/java/org/springframework/test/json/JsonConverterDelegate.java

@ -0,0 +1,61 @@ @@ -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 <T> the target type
*/
<T> 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 <T> the target type
*/
<T> T map(Object value, ResolvableType targetType) throws IOException;
/**
* Create a {@link JsonConverterDelegate} from message converters.
* @param candidates the candidates
*/
static JsonConverterDelegate of(Iterable<HttpMessageConverter<?>> candidates) {
return new DefaultJsonConverterDelegate(candidates);
}
}

8
spring-test/src/main/java/org/springframework/test/json/JsonPathValueAssert.java

@ -19,8 +19,6 @@ package org.springframework.test.json; @@ -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<JsonPathValueAs @@ -34,10 +32,8 @@ public class JsonPathValueAssert extends AbstractJsonValueAssert<JsonPathValueAs
private final String expression;
JsonPathValueAssert(@Nullable Object actual, String expression,
@Nullable HttpMessageContentConverter contentConverter) {
super(actual, JsonPathValueAssert.class, contentConverter);
JsonPathValueAssert(@Nullable Object actual, String expression, @Nullable JsonConverterDelegate converter) {
super(actual, JsonPathValueAssert.class, converter);
this.expression = expression;
}

20
spring-test/src/main/java/org/springframework/test/web/servlet/assertj/AbstractMockHttpServletResponseAssert.java

@ -26,10 +26,10 @@ import org.assertj.core.api.StringAssert; @@ -26,10 +26,10 @@ import org.assertj.core.api.StringAssert;
import org.jspecify.annotations.Nullable;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.http.HttpMessageContentConverter;
import org.springframework.test.json.AbstractJsonContentAssert;
import org.springframework.test.json.JsonContent;
import org.springframework.test.json.JsonContentAssert;
import org.springframework.test.json.JsonConverterDelegate;
import org.springframework.test.web.UriAssert;
/**
@ -44,13 +44,23 @@ import org.springframework.test.web.UriAssert; @@ -44,13 +44,23 @@ import org.springframework.test.web.UriAssert;
public abstract class AbstractMockHttpServletResponseAssert<SELF extends AbstractMockHttpServletResponseAssert<SELF, ACTUAL>, ACTUAL>
extends AbstractHttpServletResponseAssert<MockHttpServletResponse, SELF, ACTUAL> {
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<SELF extends Abstrac @@ -93,7 +103,7 @@ public abstract class AbstractMockHttpServletResponseAssert<SELF extends Abstrac
* </code></pre>
*/
public AbstractJsonContentAssert<?> bodyJson() {
return new JsonContentAssert(new JsonContent(readBody(), this.contentConverter));
return new JsonContentAssert(new JsonContent(readBody(), this.converterDelegate));
}
private String readBody() {

10
spring-test/src/main/java/org/springframework/test/web/servlet/assertj/DefaultMvcTestResult.java

@ -18,7 +18,7 @@ package org.springframework.test.web.servlet.assertj; @@ -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 { @@ -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 { @@ -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);
}
}

18
spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MockMvcTester.java

@ -30,7 +30,7 @@ import org.springframework.http.HttpMethod; @@ -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 { @@ -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 { @@ -232,7 +232,7 @@ public final class MockMvcTester {
* @return a new instance using the specified converters
*/
public MockMvcTester withHttpMessageConverters(Iterable<HttpMessageConverter<?>> 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 { @@ -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 { @@ -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 { @@ -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);
}
}

6
spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MvcTestResultAssert.java

@ -34,7 +34,7 @@ import org.jspecify.annotations.Nullable; @@ -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; @@ -51,8 +51,8 @@ import org.springframework.web.servlet.ModelAndView;
*/
public class MvcTestResultAssert extends AbstractMockHttpServletResponseAssert<MvcTestResultAssert, MvcTestResult> {
MvcTestResultAssert(MvcTestResult actual, @Nullable HttpMessageContentConverter contentConverter) {
super(contentConverter, actual, MvcTestResultAssert.class);
MvcTestResultAssert(MvcTestResult actual, @Nullable JsonConverterDelegate converterDelegate) {
super(converterDelegate, actual, MvcTestResultAssert.class);
}
@Override

14
spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java

@ -39,10 +39,10 @@ import org.springframework.http.client.ClientHttpRequestExecution; @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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);
}

16
spring-test/src/main/java/org/springframework/test/web/servlet/client/ExchangeResult.java

@ -38,7 +38,7 @@ import org.springframework.http.HttpStatus; @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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;
}
/**

2
spring-test/src/main/java/org/springframework/test/web/servlet/client/assertj/RestTestClientResponseAssert.java

@ -342,7 +342,7 @@ public class RestTestClientResponseAssert @@ -342,7 +342,7 @@ public class RestTestClientResponseAssert
* </code></pre>
*/
public AbstractJsonContentAssert<?> bodyJson() {
return new JsonContentAssert(new JsonContent(readBody(), getExchangeResult().getMessageContentConverter()));
return new JsonContentAssert(new JsonContent(readBody(), getExchangeResult().getConverterDelegate()));
}
private String readBody() {

19
spring-test/src/test/java/org/springframework/test/json/AbstractJsonContentAssertTests.java

@ -53,7 +53,6 @@ import org.springframework.core.io.FileSystemResource; @@ -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 { @@ -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 { @@ -120,10 +119,10 @@ class AbstractJsonContentAssertTests {
.hasFamilyMember("Homer");
}
private AssertProvider<AbstractJsonContentAssert<?>> forJson(@Nullable String json,
@Nullable HttpMessageContentConverter jsonContentConverter) {
private AssertProvider<AbstractJsonContentAssert<?>> forJson(
@Nullable String json, @Nullable JsonConverterDelegate converter) {
return () -> new TestJsonContentAssert(json, jsonContentConverter);
return () -> new TestJsonContentAssert(json, converter);
}
private static class FamilyAssertFactory extends InstanceOfAssertFactory<Family, FamilyAssert> {
@ -386,8 +385,8 @@ class AbstractJsonContentAssertTests { @@ -386,8 +385,8 @@ class AbstractJsonContentAssertTests {
return () -> new TestJsonContentAssert(json, null);
}
private AssertProvider<AbstractJsonContentAssert<?>> forJson(@Nullable String json, HttpMessageContentConverter jsonContentConverter) {
return () -> new TestJsonContentAssert(json, jsonContentConverter);
private AssertProvider<AbstractJsonContentAssert<?>> forJson(@Nullable String json, JsonConverterDelegate converter) {
return () -> new TestJsonContentAssert(json, converter);
}
}
@ -886,8 +885,8 @@ class AbstractJsonContentAssertTests { @@ -886,8 +885,8 @@ class AbstractJsonContentAssertTests {
private static class TestJsonContentAssert extends AbstractJsonContentAssert<TestJsonContentAssert> {
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);
}
}

68
spring-test/src/test/java/org/springframework/test/http/HttpMessageContentConverterTests.java → spring-test/src/test/java/org/springframework/test/json/DefaultJsonConverterDelegateTests.java

@ -14,7 +14,7 @@ @@ -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; @@ -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 { @@ -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 { @@ -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<Integer> data = contentConverter.convert(message, JSON, listOfIntegers);
DefaultJsonConverterDelegate converter =
new DefaultJsonConverterDelegate(List.of(firstConverter, secondConverter));
List<Integer> 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 { @@ -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<Integer> data = contentConverter.convert(createMessage("[2,3,4]"), JSON, listOfIntegers);
DefaultJsonConverterDelegate converter =
new DefaultJsonConverterDelegate(List.of(firstConverter, jacksonMessageConverter));
List<Integer> 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 { @@ -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<Integer> data = contentConverter.convert(message, JSON, listOfIntegers);
DefaultJsonConverterDelegate converter =
new DefaultJsonConverterDelegate(List.of(firstConverter, smartConverter));
List<Integer> data = converter.read(message, JSON, listOfIntegers);
assertThat(data).containsExactly(1, 2, 3);
verify(smartConverter).canRead(listOfIntegers, JSON);
}
@ -117,9 +118,9 @@ class HttpMessageContentConverterTests { @@ -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<Integer> data = contentConverter.convert(message, MediaType.TEXT_PLAIN, listOfIntegers);
DefaultJsonConverterDelegate converter =
new DefaultJsonConverterDelegate(List.of(jacksonMessageConverter, secondConverter, thirdConverter));
List<Integer> 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 { @@ -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<java.lang.Integer>]");
verify(textConverter).canRead(listOfIntegers, JSON);
verify(htmlConverter).canRead(listOfIntegers, JSON);
@ -148,9 +148,9 @@ class HttpMessageContentConverterTests { @@ -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<Integer> data = contentConverter.convertViaJson(value, listOfIntegers);
JsonConverterDelegate converter =
new DefaultJsonConverterDelegate(List.of(readConverter, firstWriteJsonConverter, secondWriteJsonConverter));
List<Integer> 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 { @@ -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<Integer> data = contentConverter.convertViaJson("[1, 2, 3]", listOfIntegers);
JsonConverterDelegate converter =
new DefaultJsonConverterDelegate(List.of(readConverter, writeConverter, jacksonMessageConverter));
List<Integer> 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 { @@ -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<Integer> data = contentConverter.convertViaJson("[1, 2, 3]", listOfIntegers);
JsonConverterDelegate converter =
new DefaultJsonConverterDelegate(List.of(readConverter, writeConverter, jacksonMessageConverter));
List<Integer> 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 { @@ -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<Integer> data = contentConverter.convertViaJson("[1, 2, 3]", listOfIntegers);
JsonConverterDelegate converterDelegate =
new DefaultJsonConverterDelegate(List.of(readConverter, writeConverter, jacksonMessageConverter));
List<Integer> 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 { @@ -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);
}

9
spring-test/src/test/java/org/springframework/test/json/JsonContentTests.java

@ -16,10 +16,11 @@ @@ -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 { @@ -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);
}
}

5
spring-test/src/test/java/org/springframework/test/json/JsonPathValueAssertTests.java

@ -30,7 +30,6 @@ import org.junit.jupiter.api.Test; @@ -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 { @@ -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() {

3
spring-test/src/test/java/org/springframework/test/web/servlet/assertj/AbstractMockHttpServletResponseAssertTests.java

@ -25,6 +25,7 @@ import org.junit.jupiter.api.Test; @@ -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 { @@ -138,7 +139,7 @@ public class AbstractMockHttpServletResponseAssertTests {
private static final class ResponseAssert extends AbstractMockHttpServletResponseAssert<ResponseAssert, MockHttpServletResponse> {
ResponseAssert(MockHttpServletResponse actual) {
super(null, actual, ResponseAssert.class);
super((JsonConverterDelegate) null, actual, ResponseAssert.class);
}
@Override

Loading…
Cancel
Save