Skip to content

Commit 756a7f1

Browse files
berruetaphilwebb
authored andcommitted
Use Jackson configuration with JsonPath
Update `JacksonTester` so that the JsonPath instance is explicitly configured with both a `JacksonJsonProvider` and a `JacksonMappingProvider`. Prior to this commit, the handling of special characters was not symmetrical between the serialization (handled via the JacksonTester) and the parsing (handled via JsonPath) due to the fact that JsonPath used `SimpleJson` as its parser. See gh-16629
1 parent 4fc813b commit 756a7f1

File tree

10 files changed

+276
-17
lines changed

10 files changed

+276
-17
lines changed

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/json/AbstractJsonMarshalTester.java

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.io.StringReader;
2727
import java.lang.reflect.Field;
2828

29+
import com.jayway.jsonpath.Configuration;
2930
import org.assertj.core.api.Assertions;
3031

3132
import org.springframework.beans.factory.ObjectFactory;
@@ -72,6 +73,8 @@ public abstract class AbstractJsonMarshalTester<T> {
7273

7374
private ResolvableType type;
7475

76+
private Configuration configuration;
77+
7578
/**
7679
* Create a new uninitialized {@link AbstractJsonMarshalTester} instance.
7780
*/
@@ -85,9 +88,22 @@ protected AbstractJsonMarshalTester() {
8588
* @param type the type under test
8689
*/
8790
public AbstractJsonMarshalTester(Class<?> resourceLoadClass, ResolvableType type) {
91+
this(resourceLoadClass, type, Configuration.defaultConfiguration());
92+
}
93+
94+
/**
95+
* Create a new {@link AbstractJsonMarshalTester} instance.
96+
* @param resourceLoadClass the source class used when loading relative classpath
97+
* resources
98+
* @param type the type under test
99+
* @param configuration the json-path configuration
100+
*/
101+
public AbstractJsonMarshalTester(Class<?> resourceLoadClass, ResolvableType type,
102+
Configuration configuration) {
88103
Assert.notNull(resourceLoadClass, "ResourceLoadClass must not be null");
89104
Assert.notNull(type, "Type must not be null");
90-
initialize(resourceLoadClass, type);
105+
Assert.notNull(configuration, "Configuration must not be null");
106+
initialize(resourceLoadClass, type, configuration);
91107
}
92108

93109
/**
@@ -97,9 +113,23 @@ public AbstractJsonMarshalTester(Class<?> resourceLoadClass, ResolvableType type
97113
* @param type the type under test
98114
*/
99115
protected final void initialize(Class<?> resourceLoadClass, ResolvableType type) {
100-
if (this.resourceLoadClass == null && this.type == null) {
116+
initialize(resourceLoadClass, type, Configuration.defaultConfiguration());
117+
}
118+
119+
/**
120+
* Initialize the marshal tester for use.
121+
* @param resourceLoadClass the source class used when loading relative classpath
122+
* resources
123+
* @param type the type under test
124+
* @param configuration the json-path configuration
125+
*/
126+
protected final void initialize(Class<?> resourceLoadClass, ResolvableType type,
127+
Configuration configuration) {
128+
if (this.resourceLoadClass == null && this.type == null
129+
&& this.configuration == null) {
101130
this.resourceLoadClass = resourceLoadClass;
102131
this.type = type;
132+
this.configuration = configuration;
103133
}
104134
}
105135

@@ -129,7 +159,8 @@ public JsonContent<T> write(T value) throws IOException {
129159
verify();
130160
Assert.notNull(value, "Value must not be null");
131161
String json = writeObject(value, this.type);
132-
return new JsonContent<>(this.resourceLoadClass, this.type, json);
162+
return new JsonContent<>(this.resourceLoadClass, this.type, json,
163+
this.configuration);
133164
}
134165

135166
/**

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/json/BasicJsonTester.java

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import java.io.InputStream;
2121
import java.nio.charset.Charset;
2222

23+
import com.jayway.jsonpath.Configuration;
24+
2325
import org.springframework.core.io.Resource;
2426
import org.springframework.util.Assert;
2527

@@ -49,6 +51,8 @@ public class BasicJsonTester {
4951

5052
private JsonLoader loader;
5153

54+
private Configuration configuration;
55+
5256
/**
5357
* Create a new uninitialized {@link BasicJsonTester} instance.
5458
*/
@@ -70,8 +74,21 @@ public BasicJsonTester(Class<?> resourceLoadClass) {
7074
* @since 1.4.1
7175
*/
7276
public BasicJsonTester(Class<?> resourceLoadClass, Charset charset) {
77+
this(resourceLoadClass, charset, Configuration.defaultConfiguration());
78+
}
79+
80+
/**
81+
* Create a new {@link BasicJsonTester} instance.
82+
* @param resourceLoadClass the source class used to load resources
83+
* @param charset the charset used to load resources
84+
* @param configuration the json-path configuration
85+
*/
86+
public BasicJsonTester(Class<?> resourceLoadClass, Charset charset,
87+
Configuration configuration) {
7388
Assert.notNull(resourceLoadClass, "ResourceLoadClass must not be null");
89+
Assert.notNull(configuration, "Configuration must not be null");
7490
this.loader = new JsonLoader(resourceLoadClass, charset);
91+
this.configuration = configuration;
7592
}
7693

7794
/**
@@ -92,8 +109,22 @@ protected final void initialize(Class<?> resourceLoadClass) {
92109
* @since 1.4.1
93110
*/
94111
protected final void initialize(Class<?> resourceLoadClass, Charset charset) {
95-
if (this.loader == null) {
112+
initialize(resourceLoadClass, charset, Configuration.defaultConfiguration());
113+
}
114+
115+
/**
116+
* Initialize the marshal tester for use.
117+
* @param resourceLoadClass the source class used when loading relative classpath
118+
* resources
119+
* @param charset the charset used when loading relative classpath resources
120+
* @param configuration the json-path configuration
121+
* @since
122+
*/
123+
protected final void initialize(Class<?> resourceLoadClass, Charset charset,
124+
Configuration configuration) {
125+
if (this.loader == null && this.configuration == null) {
96126
this.loader = new JsonLoader(resourceLoadClass, charset);
127+
this.configuration = configuration;
97128
}
98129
}
99130

@@ -165,7 +196,8 @@ private void verify() {
165196
}
166197

167198
private JsonContent<Object> getJsonContent(String json) {
168-
return new JsonContent<>(this.loader.getResourceLoadClass(), null, json);
199+
return new JsonContent<>(this.loader.getResourceLoadClass(), null, json,
200+
this.configuration);
169201
}
170202

171203
}

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/json/GsonTester.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.io.Reader;
2121

2222
import com.google.gson.Gson;
23+
import com.jayway.jsonpath.Configuration;
2324

2425
import org.springframework.beans.factory.ObjectFactory;
2526
import org.springframework.core.ResolvableType;
@@ -74,7 +75,20 @@ protected GsonTester(Gson gson) {
7475
* @see #initFields(Object, Gson)
7576
*/
7677
public GsonTester(Class<?> resourceLoadClass, ResolvableType type, Gson gson) {
77-
super(resourceLoadClass, type);
78+
this(resourceLoadClass, type, gson, Configuration.defaultConfiguration());
79+
}
80+
81+
/**
82+
* Create a new {@link GsonTester} instance.
83+
* @param resourceLoadClass the source class used to load resources
84+
* @param type the type under test
85+
* @param gson the Gson instance
86+
* @param configuration the json-path configuration
87+
* @see #initFields(Object, Gson)
88+
*/
89+
public GsonTester(Class<?> resourceLoadClass, ResolvableType type, Gson gson,
90+
Configuration configuration) {
91+
super(resourceLoadClass, type, configuration);
7892
Assert.notNull(gson, "Gson must not be null");
7993
this.gson = gson;
8094
}

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/json/JacksonTester.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
import com.fasterxml.jackson.databind.ObjectMapper;
2525
import com.fasterxml.jackson.databind.ObjectReader;
2626
import com.fasterxml.jackson.databind.ObjectWriter;
27+
import com.jayway.jsonpath.Configuration;
28+
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
29+
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
2730

2831
import org.springframework.beans.factory.ObjectFactory;
2932
import org.springframework.core.ResolvableType;
@@ -86,7 +89,9 @@ public JacksonTester(Class<?> resourceLoadClass, ResolvableType type,
8689

8790
public JacksonTester(Class<?> resourceLoadClass, ResolvableType type,
8891
ObjectMapper objectMapper, Class<?> view) {
89-
super(resourceLoadClass, type);
92+
super(resourceLoadClass, type, Configuration.builder()
93+
.jsonProvider(new JacksonJsonProvider(objectMapper))
94+
.mappingProvider(new JacksonMappingProvider(objectMapper)).build());
9095
Assert.notNull(objectMapper, "ObjectMapper must not be null");
9196
this.objectMapper = objectMapper;
9297
this.view = view;

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.boot.test.json;
1818

19+
import com.jayway.jsonpath.Configuration;
1920
import org.assertj.core.api.AssertProvider;
2021

2122
import org.springframework.core.ResolvableType;
@@ -38,18 +39,34 @@ public final class JsonContent<T> implements AssertProvider<JsonContentAssert> {
3839

3940
private final String json;
4041

42+
private final Configuration configuration;
43+
4144
/**
4245
* Create a new {@link JsonContent} instance.
4346
* @param resourceLoadClass the source class used to load resources
4447
* @param type the type under test (or {@code null} if not known)
4548
* @param json the actual JSON content
4649
*/
4750
public JsonContent(Class<?> resourceLoadClass, ResolvableType type, String json) {
51+
this(resourceLoadClass, type, json, Configuration.defaultConfiguration());
52+
}
53+
54+
/**
55+
* Create a new {@link JsonContent} instance.
56+
* @param resourceLoadClass the source class used to load resources
57+
* @param type the type under test (or {@code null} if not known)
58+
* @param json the actual JSON content
59+
* @param configuration the json-path configuration
60+
*/
61+
public JsonContent(Class<?> resourceLoadClass, ResolvableType type, String json,
62+
Configuration configuration) {
4863
Assert.notNull(resourceLoadClass, "ResourceLoadClass must not be null");
4964
Assert.notNull(json, "JSON must not be null");
65+
Assert.notNull(configuration, "Configuration must not be null");
5066
this.resourceLoadClass = resourceLoadClass;
5167
this.type = type;
5268
this.json = json;
69+
this.configuration = configuration;
5370
}
5471

5572
/**
@@ -61,7 +78,8 @@ public JsonContent(Class<?> resourceLoadClass, ResolvableType type, String json)
6178
@Override
6279
@Deprecated
6380
public JsonContentAssert assertThat() {
64-
return new JsonContentAssert(this.resourceLoadClass, this.json);
81+
return new JsonContentAssert(this.resourceLoadClass, null, this.json,
82+
this.configuration);
6583
}
6684

6785
/**

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/json/JsonContentAssert.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.List;
2323
import java.util.Map;
2424

25+
import com.jayway.jsonpath.Configuration;
2526
import com.jayway.jsonpath.JsonPath;
2627
import org.assertj.core.api.AbstractAssert;
2728
import org.assertj.core.api.AbstractBooleanAssert;
@@ -51,6 +52,8 @@ public class JsonContentAssert extends AbstractAssert<JsonContentAssert, CharSeq
5152

5253
private final JsonLoader loader;
5354

55+
private final Configuration configuration;
56+
5457
/**
5558
* Create a new {@link JsonContentAssert} instance that will load resources as UTF-8.
5659
* @param resourceLoadClass the source class used to load resources
@@ -70,7 +73,21 @@ public JsonContentAssert(Class<?> resourceLoadClass, CharSequence json) {
7073
*/
7174
public JsonContentAssert(Class<?> resourceLoadClass, Charset charset,
7275
CharSequence json) {
76+
this(resourceLoadClass, charset, json, Configuration.defaultConfiguration());
77+
}
78+
79+
/**
80+
* Create a new {@link JsonContentAssert} instance that will load resources in the
81+
* given {@code charset}.
82+
* @param resourceLoadClass the source class used to load resources
83+
* @param charset the charset of the JSON resources
84+
* @param json the actual JSON content
85+
* @param configuration the json-path configuration
86+
*/
87+
public JsonContentAssert(Class<?> resourceLoadClass, Charset charset,
88+
CharSequence json, Configuration configuration) {
7389
super(json, JsonContentAssert.class);
90+
this.configuration = configuration;
7491
this.loader = new JsonLoader(resourceLoadClass, charset);
7592
}
7693

@@ -1109,7 +1126,8 @@ private boolean isEmpty() {
11091126
public Object getValue(boolean required) {
11101127
try {
11111128
CharSequence json = JsonContentAssert.this.actual;
1112-
return this.jsonPath.read((json != null) ? json.toString() : null);
1129+
return this.jsonPath.read((json != null) ? json.toString() : null,
1130+
JsonContentAssert.this.configuration);
11131131
}
11141132
catch (Exception ex) {
11151133
if (!required) {

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/json/JsonbTester.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
import javax.json.bind.Jsonb;
2323

24+
import com.jayway.jsonpath.Configuration;
25+
2426
import org.springframework.beans.factory.ObjectFactory;
2527
import org.springframework.core.ResolvableType;
2628
import org.springframework.util.Assert;
@@ -74,7 +76,20 @@ protected JsonbTester(Jsonb jsonb) {
7476
* @see #initFields(Object, Jsonb)
7577
*/
7678
public JsonbTester(Class<?> resourceLoadClass, ResolvableType type, Jsonb jsonb) {
77-
super(resourceLoadClass, type);
79+
this(resourceLoadClass, type, jsonb, Configuration.defaultConfiguration());
80+
}
81+
82+
/**
83+
* Create a new {@link JsonbTester} instance.
84+
* @param resourceLoadClass the source class used to load resources
85+
* @param type the type under test
86+
* @param jsonb the Jsonb instance
87+
* @param configuration the json-path configuration
88+
* @see #initFields(Object, Jsonb)
89+
*/
90+
public JsonbTester(Class<?> resourceLoadClass, ResolvableType type, Jsonb jsonb,
91+
Configuration configuration) {
92+
super(resourceLoadClass, type, configuration);
7893
Assert.notNull(jsonb, "Jsonb must not be null");
7994
this.jsonb = jsonb;
8095
}

0 commit comments

Comments
 (0)