Browse Source

Add JSON matcher to assert on request body

Support asserting JSON regardless of order and formatting.
Based on same JsonExpectationHelper used in ContentResultMatchers.

Issue: SPR-13919
pull/1740/merge
Bronwyn Perry-Huston 9 years ago committed by sdeleuze
parent
commit
d64f2eb038
  1. 46
      spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java
  2. 50
      spring-test/src/test/java/org/springframework/test/web/client/match/ContentRequestMatchersTests.java

46
spring-test/src/main/java/org/springframework/test/web/client/match/ContentRequestMatchers.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@ -23,6 +23,7 @@ import javax.xml.transform.Source; @@ -23,6 +23,7 @@ import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import org.hamcrest.Matcher;
import org.springframework.test.util.JsonExpectationsHelper;
import org.w3c.dom.Node;
import org.springframework.http.HttpHeaders;
@ -49,6 +50,8 @@ public class ContentRequestMatchers { @@ -49,6 +50,8 @@ public class ContentRequestMatchers {
private final XmlExpectationsHelper xmlHelper;
private final JsonExpectationsHelper jsonHelper;
/**
* Class constructor, not for direct instantiation.
@ -56,6 +59,7 @@ public class ContentRequestMatchers { @@ -56,6 +59,7 @@ public class ContentRequestMatchers {
*/
protected ContentRequestMatchers() {
this.xmlHelper = new XmlExpectationsHelper();
this.jsonHelper = new JsonExpectationsHelper();
}
@ -194,6 +198,46 @@ public class ContentRequestMatchers { @@ -194,6 +198,46 @@ public class ContentRequestMatchers {
};
}
/**
* Parse the expected and actual strings as JSON and assert the two
* are "similar" - i.e. they contain the same attribute-value pairs
* regardless of formatting with a lenient checking (extensible, and non-strict array
* ordering).
* <p>Use of this matcher requires the <a
* href="http://jsonassert.skyscreamer.org/">JSONassert<a/> library.
* @param expectedJsonContent the expected JSON content
* @since 5.0.5
*/
public RequestMatcher json(final String expectedJsonContent) {
return json(expectedJsonContent, false);
}
/**
* Parse the request body and the given string as JSON and assert the two
* are "similar" - i.e. they contain the same attribute-value pairs
* regardless of formatting.
* <p>Can compare in two modes, depending on {@code strict} parameter value:
* <ul>
* <li>{@code true}: strict checking. Not extensible, and strict array ordering.</li>
* <li>{@code false}: lenient checking. Extensible, and non-strict array ordering.</li>
* </ul>
* <p>Use of this matcher requires the <a
* href="http://jsonassert.skyscreamer.org/">JSONassert<a/> library.
* @param expectedJsonContent the expected JSON content
* @param strict enables strict checking
* @since 5.0.5
*/
public RequestMatcher json(final String expectedJsonContent, final boolean strict) {
return request -> {
try {
MockClientHttpRequest mockRequest = (MockClientHttpRequest) request;
jsonHelper.assertJsonEqual(expectedJsonContent, mockRequest.getBodyAsString(), strict);
} catch (Exception e) {
throw new AssertionError("Failed to parse expected or actual JSON request content", e);
}
};
}
/**
* Abstract base class for XML {@link RequestMatcher}'s.

50
spring-test/src/test/java/org/springframework/test/web/client/match/ContentRequestMatchersTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 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.
@ -142,4 +142,52 @@ public class ContentRequestMatchersTests { @@ -142,4 +142,52 @@ public class ContentRequestMatchersTests {
MockRestRequestMatchers.content().node(hasXPath("/foo/bar/bar")).match(this.request);
}
@Test
public void testJsonLenientMatch() throws Exception {
String content = "{\n \"foo array\":[\"first\",\"second\"] , \"someExtraProperty\": \"which is allowed\" \n}";
this.request.getBody().write(content.getBytes());
MockRestRequestMatchers.content().json("{\n \"foo array\":[\"second\",\"first\"] \n}")
.match(this.request);
MockRestRequestMatchers.content().json("{\n \"foo array\":[\"second\",\"first\"] \n}", false)
.match(this.request);
}
@Test
public void testJsonStrictMatch() throws Exception {
String content = "{\n \"foo\": \"bar\", \"foo array\":[\"first\",\"second\"] \n}";
this.request.getBody().write(content.getBytes());
MockRestRequestMatchers
.content()
.json("{\n \"foo array\":[\"first\",\"second\"] , \"foo\": \"bar\" \n}", true)
.match(this.request);
}
@Test(expected = AssertionError.class)
public void testJsonLenientNoMatch() throws Exception {
String content = "{\n \"bar\" : \"foo\" \n}";
this.request.getBody().write(content.getBytes());
MockRestRequestMatchers
.content()
.json("{\n \"foo\" : \"bar\" \n}")
.match(this.request);
MockRestRequestMatchers
.content()
.json("{\n \"foo\" : \"bar\" \n}", false)
.match(this.request);
}
@Test(expected = AssertionError.class)
public void testJsonStrictNoMatch() throws Exception {
String content = "{\n \"foo array\":[\"first\",\"second\"] , \"someExtraProperty\": \"which is NOT allowed\" \n}";
this.request.getBody().write(content.getBytes());
MockRestRequestMatchers
.content()
.json("{\n \"foo array\":[\"second\",\"first\"] \n}", true)
.match(this.request);
}
}

Loading…
Cancel
Save