Browse Source

Configure JsonPath in RestTestClient with MappingProvider

Closes gh-35793
pull/35808/merge
rstoyanchev 4 weeks ago
parent
commit
f80b79bc45
  1. 40
      spring-test/src/main/java/org/springframework/test/web/servlet/client/DefaultRestTestClient.java
  2. 14
      spring-test/src/test/java/org/springframework/test/web/servlet/client/JsonPathAssertionTests.java

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

@ -28,9 +28,13 @@ import java.util.concurrent.atomic.AtomicLong; @@ -28,9 +28,13 @@ import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import java.util.function.Function;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.TypeRef;
import com.jayway.jsonpath.spi.mapper.MappingProvider;
import org.jspecify.annotations.Nullable;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.ResolvableType;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
@ -486,7 +490,8 @@ class DefaultRestTestClient implements RestTestClient { @@ -486,7 +490,8 @@ class DefaultRestTestClient implements RestTestClient {
@Override
public JsonPathAssertions jsonPath(String expression) {
return new JsonPathAssertions(this, getBodyAsString(), expression, null);
Configuration config = JsonPathConfigurationProvider.getConfiguration(this.result);
return new JsonPathAssertions(this, getBodyAsString(), expression, config);
}
@Override
@ -540,4 +545,37 @@ class DefaultRestTestClient implements RestTestClient { @@ -540,4 +545,37 @@ class DefaultRestTestClient implements RestTestClient {
}
}
private static class JsonPathConfigurationProvider {
static Configuration getConfiguration(EntityExchangeResult<?> result) {
Configuration config = Configuration.defaultConfiguration();
JsonConverterDelegate delegate = result.getJsonConverterDelegate();
return (delegate != null ? config.mappingProvider(new MessageConverterMappingProvider(delegate)) : config);
}
}
private record MessageConverterMappingProvider(JsonConverterDelegate delegate) implements MappingProvider {
@Override
public <T> T map(Object value, Class<T> targetType, Configuration configuration) {
return mapToTargetType(value, ResolvableType.forClass(targetType));
}
@Override
public <T> T map(Object value, TypeRef<T> targetType, Configuration configuration) {
return mapToTargetType(value, ResolvableType.forType(targetType.getType()));
}
private <T> T mapToTargetType(Object value, ResolvableType targetType) {
try {
return delegate().map(value, targetType);
}
catch (IOException ex) {
throw new IllegalStateException("Failed to map " + value + " to " + targetType, ex);
}
}
}
}

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

@ -23,6 +23,7 @@ import java.util.Map; @@ -23,6 +23,7 @@ import java.util.Map;
import org.hamcrest.MatcherAssert;
import org.junit.jupiter.api.Test;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.test.web.Person;
@ -106,6 +107,19 @@ class JsonPathAssertionTests { @@ -106,6 +107,19 @@ class JsonPathAssertionTests {
.jsonPath("$.performers[1].name").value(v -> MatcherAssert.assertThat(v, equalTo("Yehudi Menuhin")));
}
@Test
void valueConsumer() {
client.get().uri("/music/people")
.exchange()
.expectBody()
.jsonPath("$.composers[0].name").value(
String.class,
name -> assertThat(name).isEqualTo("Johann Sebastian Bach"))
.jsonPath("$.composers[0].name").value(
ParameterizedTypeReference.forType(String.class),
name -> assertThat(name).isEqualTo("Johann Sebastian Bach"));
}
@Test
void hamcrestMatcher() {
client.get().uri("/music/people")

Loading…
Cancel
Save