Skip to content

Commit 920be8e

Browse files
elgleidsonsbrannen
authored andcommitted
Add support for strict JSON comparison in WebTestClient
Prior to this commit, WebTestClient only supported "lenient" comparison of the expected JSON body. This commit introduces an overloaded variant of `json()` in the BodyContentSpec that accepts an additional boolean flag to specify whether a "strict" comparison should be performed. This new feature is analogous to the existing support in MockMvc. Closes gh-27993
1 parent a13ad3e commit 920be8e

File tree

3 files changed

+64
-5
lines changed

3 files changed

+64
-5
lines changed

spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,10 +659,10 @@ public EntityExchangeResult<Void> isEmpty() {
659659
}
660660

661661
@Override
662-
public BodyContentSpec json(String json) {
662+
public BodyContentSpec json(String json, boolean strict) {
663663
this.result.assertWithDiagnostics(() -> {
664664
try {
665-
new JsonExpectationsHelper().assertJsonEqual(json, getBodyAsString());
665+
new JsonExpectationsHelper().assertJsonEqual(json, getBodyAsString(), strict);
666666
}
667667
catch (Exception ex) {
668668
throw new AssertionError("JSON parsing error", ex);

spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,24 @@ interface BodyContentSpec {
979979
* on to be on the classpath.
980980
* @param expectedJson the expected JSON content.
981981
*/
982-
BodyContentSpec json(String expectedJson);
982+
default BodyContentSpec json(String expectedJson) {
983+
return json(expectedJson, false);
984+
}
985+
986+
/**
987+
* Parse the expected and actual response content as JSON and perform a
988+
* comparison in two modes, depending on {@code strict} parameter value, verifying the same attribute-value pairs.
989+
* <ul>
990+
* <li>{@code true}: strict checking.
991+
* <li>{@code false}: lenient checking.
992+
* </ul>
993+
* <p>Use of this option requires the
994+
* <a href="https://jsonassert.skyscreamer.org/">JSONassert</a> library
995+
* on to be on the classpath.
996+
* @param expectedJson the expected JSON content.
997+
* @param strict enables strict checking
998+
*/
999+
BodyContentSpec json(String expectedJson, boolean strict);
9831000

9841001
/**
9851002
* Parse expected and actual response content as XML and assert that

spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/JsonContentTests.java

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@
3131
import org.springframework.web.bind.annotation.RequestMapping;
3232
import org.springframework.web.bind.annotation.RestController;
3333

34+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
3435
import static org.hamcrest.Matchers.containsString;
3536

3637

37-
3838
/**
3939
* Samples of tests using {@link WebTestClient} with serialized JSON content.
4040
*
@@ -49,13 +49,32 @@ public class JsonContentTests {
4949

5050
@Test
5151
public void jsonContent() {
52-
this.client.get().uri("/persons")
52+
this.client.get().uri("/persons/extended")
5353
.accept(MediaType.APPLICATION_JSON)
5454
.exchange()
5555
.expectStatus().isOk()
5656
.expectBody().json("[{\"name\":\"Jane\"},{\"name\":\"Jason\"},{\"name\":\"John\"}]");
5757
}
5858

59+
@Test
60+
public void jsonContentStrictFail() {
61+
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> this.client.get().uri("/persons/extended")
62+
.accept(MediaType.APPLICATION_JSON)
63+
.exchange()
64+
.expectStatus().isOk()
65+
.expectBody().json("[{\"name\":\"Jane\"},{\"name\":\"Jason\"},{\"name\":\"John\"}]", true)
66+
);
67+
}
68+
69+
@Test
70+
public void jsonContentStrict() {
71+
this.client.get().uri("/persons/extended")
72+
.accept(MediaType.APPLICATION_JSON)
73+
.exchange()
74+
.expectStatus().isOk()
75+
.expectBody().json("[{\"name\":\"Jane\",\"surname\":\"Williams\"},{\"name\":\"Jason\",\"surname\":\"Johnson\"},{\"name\":\"John\",\"surname\":\"Smith\"}]", true);
76+
}
77+
5978
@Test
6079
public void jsonPathIsEqualTo() {
6180
this.client.get().uri("/persons")
@@ -98,6 +117,11 @@ Flux<Person> getPersons() {
98117
return Flux.just(new Person("Jane"), new Person("Jason"), new Person("John"));
99118
}
100119

120+
@GetMapping("/extended")
121+
Flux<ExtendedPerson> getExtendedPersons() {
122+
return Flux.just(new ExtendedPerson("Jane", "Williams"), new ExtendedPerson("Jason", "Johnson"), new ExtendedPerson("John", "Smith"));
123+
}
124+
101125
@GetMapping("/{name}")
102126
Person getPerson(@PathVariable String name) {
103127
return new Person(name);
@@ -109,4 +133,22 @@ ResponseEntity<String> savePerson(@RequestBody Person person) {
109133
}
110134
}
111135

136+
static class ExtendedPerson {
137+
private String name;
138+
private String surname;
139+
140+
public ExtendedPerson(String name, String surname) {
141+
this.name = name;
142+
this.surname = surname;
143+
}
144+
145+
public String getName() {
146+
return name;
147+
}
148+
149+
public String getSurname() {
150+
return surname;
151+
}
152+
}
153+
112154
}

0 commit comments

Comments
 (0)