Skip to content

Commit f80b79b

Browse files
committed
Configure JsonPath in RestTestClient with MappingProvider
Closes gh-35793
1 parent adffd3d commit f80b79b

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

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

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,13 @@
2828
import java.util.function.Consumer;
2929
import java.util.function.Function;
3030

31+
import com.jayway.jsonpath.Configuration;
32+
import com.jayway.jsonpath.TypeRef;
33+
import com.jayway.jsonpath.spi.mapper.MappingProvider;
3134
import org.jspecify.annotations.Nullable;
3235

3336
import org.springframework.core.ParameterizedTypeReference;
37+
import org.springframework.core.ResolvableType;
3438
import org.springframework.http.HttpHeaders;
3539
import org.springframework.http.HttpMethod;
3640
import org.springframework.http.HttpRequest;
@@ -486,7 +490,8 @@ public BodyContentSpec xml(String expectedXml) {
486490

487491
@Override
488492
public JsonPathAssertions jsonPath(String expression) {
489-
return new JsonPathAssertions(this, getBodyAsString(), expression, null);
493+
Configuration config = JsonPathConfigurationProvider.getConfiguration(this.result);
494+
return new JsonPathAssertions(this, getBodyAsString(), expression, config);
490495
}
491496

492497
@Override
@@ -540,4 +545,37 @@ public byte[] getRequestContent(String requestId) {
540545
}
541546
}
542547

548+
549+
private static class JsonPathConfigurationProvider {
550+
551+
static Configuration getConfiguration(EntityExchangeResult<?> result) {
552+
Configuration config = Configuration.defaultConfiguration();
553+
JsonConverterDelegate delegate = result.getJsonConverterDelegate();
554+
return (delegate != null ? config.mappingProvider(new MessageConverterMappingProvider(delegate)) : config);
555+
}
556+
}
557+
558+
559+
private record MessageConverterMappingProvider(JsonConverterDelegate delegate) implements MappingProvider {
560+
561+
@Override
562+
public <T> T map(Object value, Class<T> targetType, Configuration configuration) {
563+
return mapToTargetType(value, ResolvableType.forClass(targetType));
564+
}
565+
566+
@Override
567+
public <T> T map(Object value, TypeRef<T> targetType, Configuration configuration) {
568+
return mapToTargetType(value, ResolvableType.forType(targetType.getType()));
569+
}
570+
571+
private <T> T mapToTargetType(Object value, ResolvableType targetType) {
572+
try {
573+
return delegate().map(value, targetType);
574+
}
575+
catch (IOException ex) {
576+
throw new IllegalStateException("Failed to map " + value + " to " + targetType, ex);
577+
}
578+
}
579+
}
580+
543581
}

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.hamcrest.MatcherAssert;
2424
import org.junit.jupiter.api.Test;
2525

26+
import org.springframework.core.ParameterizedTypeReference;
2627
import org.springframework.http.HttpHeaders;
2728
import org.springframework.http.MediaType;
2829
import org.springframework.test.web.Person;
@@ -106,6 +107,19 @@ void equality() {
106107
.jsonPath("$.performers[1].name").value(v -> MatcherAssert.assertThat(v, equalTo("Yehudi Menuhin")));
107108
}
108109

110+
@Test
111+
void valueConsumer() {
112+
client.get().uri("/music/people")
113+
.exchange()
114+
.expectBody()
115+
.jsonPath("$.composers[0].name").value(
116+
String.class,
117+
name -> assertThat(name).isEqualTo("Johann Sebastian Bach"))
118+
.jsonPath("$.composers[0].name").value(
119+
ParameterizedTypeReference.forType(String.class),
120+
name -> assertThat(name).isEqualTo("Johann Sebastian Bach"));
121+
}
122+
109123
@Test
110124
void hamcrestMatcher() {
111125
client.get().uri("/music/people")

0 commit comments

Comments
 (0)