20
20
import java .lang .reflect .Method ;
21
21
import java .text .ParseException ;
22
22
import java .util .List ;
23
+ import java .util .Map ;
23
24
24
- import com .jayway .jsonpath .InvalidPathException ;
25
- import com .jayway .jsonpath .JsonPath ;
26
25
import org .hamcrest .Matcher ;
27
26
28
27
import org .springframework .util .Assert ;
29
28
import org .springframework .util .ReflectionUtils ;
30
29
31
- import static org .hamcrest .MatcherAssert .*;
32
- import static org .springframework .test .util .AssertionErrors .*;
30
+ import com .jayway .jsonpath .InvalidPathException ;
31
+ import com .jayway .jsonpath .JsonPath ;
32
+
33
+ import static org .hamcrest .MatcherAssert .assertThat ;
34
+ import static org .hamcrest .core .IsInstanceOf .instanceOf ;
35
+ import static org .springframework .test .util .AssertionErrors .assertEquals ;
36
+ import static org .springframework .test .util .AssertionErrors .assertTrue ;
37
+ import static org .springframework .test .util .AssertionErrors .fail ;
33
38
34
39
/**
35
40
* A helper class for applying assertions via JSON path expressions.
39
44
*
40
45
* @author Rossen Stoyanchev
41
46
* @author Juergen Hoeller
47
+ * @author Craig Andrews
48
+ * @author Sam Brannen
42
49
* @since 3.2
43
50
*/
44
51
public class JsonPathExpectationsHelper {
@@ -69,92 +76,130 @@ public class JsonPathExpectationsHelper {
69
76
70
77
71
78
/**
72
- * Construct a new JsonPathExpectationsHelper.
73
- * @param expression the JsonPath expression
74
- * @param args arguments to parameterize the JSON path expression with
79
+ * Construct a new {@code JsonPathExpectationsHelper} .
80
+ * @param expression the {@link JsonPath} expression; never {@code null} or empty
81
+ * @param args arguments to parameterize the {@code JsonPath} expression, with
75
82
* formatting specifiers defined in {@link String#format(String, Object...)}
76
83
*/
77
84
public JsonPathExpectationsHelper (String expression , Object ... args ) {
85
+ Assert .hasText (expression , "expression must not be null or empty" );
78
86
this .expression = String .format (expression , args );
79
87
this .jsonPath = (JsonPath ) ReflectionUtils .invokeMethod (
80
88
compileMethod , null , this .expression , emptyFilters );
81
89
}
82
90
83
91
84
92
/**
85
- * Evaluate the JSON path and assert the resulting value with the given {@code Matcher}.
86
- * @param content the response content
87
- * @param matcher the matcher to assert on the resulting json path
93
+ * Evaluate the JSON path expression against the supplied {@code content}
94
+ * and assert the resulting value with the given {@code Matcher}.
95
+ * @param content the JSON response content
96
+ * @param matcher the matcher with which to assert the result
88
97
*/
89
98
@ SuppressWarnings ("unchecked" )
90
99
public <T > void assertValue (String content , Matcher <T > matcher ) throws ParseException {
91
100
T value = (T ) evaluateJsonPath (content );
92
- assertThat ("JSON path " + this .expression , value , matcher );
93
- }
94
-
95
- private Object evaluateJsonPath (String content ) throws ParseException {
96
- String message = "No value for JSON path: " + this .expression + ", exception: " ;
97
- try {
98
- return this .jsonPath .read (content );
99
- }
100
- catch (InvalidPathException ex ) {
101
- throw new AssertionError (message + ex .getMessage ());
102
- }
103
- catch (ArrayIndexOutOfBoundsException ex ) {
104
- throw new AssertionError (message + ex .getMessage ());
105
- }
106
- catch (IndexOutOfBoundsException ex ) {
107
- throw new AssertionError (message + ex .getMessage ());
108
- }
101
+ assertThat ("JSON path \" " + this .expression + "\" " , value , matcher );
109
102
}
110
103
111
104
/**
112
- * Apply the JSON path and assert the resulting value.
105
+ * Evaluate the JSON path expression against the supplied {@code content}
106
+ * and assert that the result is equal to the expected value.
107
+ * @param content the JSON response content
108
+ * @param expectedValue the expected value
113
109
*/
114
- public void assertValue (String responseContent , Object expectedValue ) throws ParseException {
115
- Object actualValue = evaluateJsonPath (responseContent );
110
+ public void assertValue (String content , Object expectedValue ) throws ParseException {
111
+ Object actualValue = evaluateJsonPath (content );
116
112
if ((actualValue instanceof List ) && !(expectedValue instanceof List )) {
117
113
@ SuppressWarnings ("rawtypes" )
118
114
List actualValueList = (List ) actualValue ;
119
115
if (actualValueList .isEmpty ()) {
120
116
fail ("No matching value for JSON path \" " + this .expression + "\" " );
121
117
}
122
118
if (actualValueList .size () != 1 ) {
123
- fail ("Got a list of values " + actualValue + " instead of the value " + expectedValue );
119
+ fail ("Got a list of values " + actualValue + " instead of the expected single value " + expectedValue );
124
120
}
125
121
actualValue = actualValueList .get (0 );
126
122
}
127
123
else if (actualValue != null && expectedValue != null ) {
128
- assertEquals ("For JSON path " + this .expression + " type of value" ,
129
- expectedValue .getClass (), actualValue .getClass ());
124
+ assertEquals ("For JSON path \" " + this .expression + "\" , type of value" ,
125
+ expectedValue .getClass (). getName () , actualValue .getClass (). getName ());
130
126
}
131
- assertEquals ("JSON path " + this .expression , expectedValue , actualValue );
127
+ assertEquals ("JSON path \" " + this .expression + "\" " , expectedValue , actualValue );
128
+ }
129
+
130
+ /**
131
+ * Evaluate the JSON path expression against the supplied {@code content}
132
+ * and assert that the resulting value is a {@link String}.
133
+ * @param content the JSON response content
134
+ * @since 4.2.1
135
+ */
136
+ public void assertValueIsString (String content ) throws ParseException {
137
+ Object value = assertExistsAndReturn (content );
138
+ String reason = "Expected string at JSON path " + this .expression + " but found " + value ;
139
+ assertThat (reason , value , instanceOf (String .class ));
140
+ }
141
+
142
+ /**
143
+ * Evaluate the JSON path expression against the supplied {@code content}
144
+ * and assert that the resulting value is a {@link Boolean}.
145
+ * @param content the JSON response content
146
+ * @since 4.2.1
147
+ */
148
+ public void assertValueIsBoolean (String content ) throws ParseException {
149
+ Object value = assertExistsAndReturn (content );
150
+ String reason = "Expected boolean at JSON path " + this .expression + " but found " + value ;
151
+ assertThat (reason , value , instanceOf (Boolean .class ));
152
+ }
153
+
154
+ /**
155
+ * Evaluate the JSON path expression against the supplied {@code content}
156
+ * and assert that the resulting value is a {@link Number}.
157
+ * @param content the JSON response content
158
+ * @since 4.2.1
159
+ */
160
+ public void assertValueIsNumber (String content ) throws ParseException {
161
+ Object value = assertExistsAndReturn (content );
162
+ String reason = "Expected number at JSON path " + this .expression + " but found " + value ;
163
+ assertThat (reason , value , instanceOf (Number .class ));
132
164
}
133
165
134
166
/**
135
- * Apply the JSON path and assert the resulting value is an array.
167
+ * Evaluate the JSON path expression against the supplied {@code content}
168
+ * and assert that the resulting value is an array.
169
+ * @param content the JSON response content
136
170
*/
137
- public void assertValueIsArray (String responseContent ) throws ParseException {
138
- Object actualValue = evaluateJsonPath (responseContent );
139
- assertTrue ("No value for JSON path \" " + this .expression + "\" " , actualValue != null );
140
- String reason = "Expected array at JSON path " + this .expression + " but found " + actualValue ;
141
- assertTrue (reason , actualValue instanceof List );
171
+ public void assertValueIsArray (String content ) throws ParseException {
172
+ Object value = assertExistsAndReturn (content );
173
+ String reason = "Expected array for JSON path \" " + this .expression + "\" but found " + value ;
174
+ assertTrue (reason , value instanceof List );
142
175
}
143
176
144
177
/**
145
- * Evaluate the JSON path and assert the resulting content exists.
178
+ * Evaluate the JSON path expression against the supplied {@code content}
179
+ * and assert that the resulting value is a {@link Map}.
180
+ * @param content the JSON response content
181
+ * @since 4.2.1
182
+ */
183
+ public void assertValueIsMap (String content ) throws ParseException {
184
+ Object value = assertExistsAndReturn (content );
185
+ String reason = "Expected map at JSON path " + this .expression + " but found " + value ;
186
+ assertThat (reason , value , instanceOf (Map .class ));
187
+ }
188
+
189
+ /**
190
+ * Evaluate the JSON path expression against the supplied {@code content}
191
+ * and assert that the resulting value exists.
192
+ * @param content the JSON response content
146
193
*/
147
194
public void exists (String content ) throws ParseException {
148
- Object value = evaluateJsonPath (content );
149
- String reason = "No value for JSON path " + this .expression ;
150
- assertTrue (reason , value != null );
151
- if (List .class .isInstance (value )) {
152
- assertTrue (reason , !((List <?>) value ).isEmpty ());
153
- }
195
+ assertExistsAndReturn (content );
154
196
}
155
197
156
198
/**
157
- * Evaluate the JSON path and assert it doesn't point to any content.
199
+ * Evaluate the JSON path expression against the supplied {@code content}
200
+ * and assert that the resulting value is empty (i.e., that a match for
201
+ * the JSON path expression does not exist in the supplied content).
202
+ * @param content the JSON response content
158
203
*/
159
204
public void doesNotExist (String content ) throws ParseException {
160
205
Object value ;
@@ -173,4 +218,30 @@ public void doesNotExist(String content) throws ParseException {
173
218
}
174
219
}
175
220
221
+ private Object evaluateJsonPath (String content ) throws ParseException {
222
+ String message = "No value for JSON path \" " + this .expression + "\" , exception: " ;
223
+ try {
224
+ return this .jsonPath .read (content );
225
+ }
226
+ catch (InvalidPathException ex ) {
227
+ throw new AssertionError (message + ex .getMessage ());
228
+ }
229
+ catch (ArrayIndexOutOfBoundsException ex ) {
230
+ throw new AssertionError (message + ex .getMessage ());
231
+ }
232
+ catch (IndexOutOfBoundsException ex ) {
233
+ throw new AssertionError (message + ex .getMessage ());
234
+ }
235
+ }
236
+
237
+ private Object assertExistsAndReturn (String content ) throws ParseException {
238
+ Object value = evaluateJsonPath (content );
239
+ String reason = "No value for JSON path \" " + this .expression + "\" " ;
240
+ assertTrue (reason , value != null );
241
+ if (List .class .isInstance (value )) {
242
+ assertTrue (reason , !((List <?>) value ).isEmpty ());
243
+ }
244
+ return value ;
245
+ }
246
+
176
247
}
0 commit comments