diff --git a/spring-test/src/main/java/org/springframework/test/util/JsonExpectationsHelper.java b/spring-test/src/main/java/org/springframework/test/util/JsonExpectationsHelper.java
index 4de0dba6eee..7c6489a6da0 100644
--- a/spring-test/src/main/java/org/springframework/test/util/JsonExpectationsHelper.java
+++ b/spring-test/src/main/java/org/springframework/test/util/JsonExpectationsHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2022 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.
@@ -32,8 +32,8 @@ public class JsonExpectationsHelper {
/**
* 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).
+ * regardless of formatting with lenient checking (extensible content and
+ * non-strict array ordering).
* @param expected the expected JSON content
* @param actual the actual JSON content
* @since 4.1
@@ -47,14 +47,14 @@ public class JsonExpectationsHelper {
* 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.
- *
Can compare in two modes, depending on {@code strict} parameter value:
+ *
Can compare in two modes, depending on the {@code strict} parameter value:
*
- * - {@code true}: strict checking. Not extensible, and strict array ordering.
- * - {@code false}: lenient checking. Extensible, and non-strict array ordering.
+ * - {@code true}: strict checking. Not extensible and strict array ordering.
+ * - {@code false}: lenient checking. Extensible and non-strict array ordering.
*
* @param expected the expected JSON content
* @param actual the actual JSON content
- * @param strict enables strict checking
+ * @param strict enables strict checking if {@code true}
* @since 4.2
*/
public void assertJsonEqual(String expected, String actual, boolean strict) throws Exception {
diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java
index 8628ef26226..a3cc4c2890e 100644
--- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java
+++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClient.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2021 the original author or authors.
+ * Copyright 2002-2022 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.
@@ -659,10 +659,10 @@ class DefaultWebTestClient implements WebTestClient {
}
@Override
- public BodyContentSpec json(String json) {
+ public BodyContentSpec json(String json, boolean strict) {
this.result.assertWithDiagnostics(() -> {
try {
- new JsonExpectationsHelper().assertJsonEqual(json, getBodyAsString());
+ new JsonExpectationsHelper().assertJsonEqual(json, getBodyAsString(), strict);
}
catch (Exception ex) {
throw new AssertionError("JSON parsing error", ex);
diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java
index 141428f171a..481a8d999e8 100644
--- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java
+++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2021 the original author or authors.
+ * Copyright 2002-2022 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.
@@ -973,13 +973,37 @@ public interface WebTestClient {
/**
* Parse the expected and actual response content as JSON and perform a
- * "lenient" comparison verifying the same attribute-value pairs.
- * Use of this option requires the
+ * comparison verifying that they contain the same attribute-value pairs
+ * regardless of formatting with lenient checking (extensible
+ * and non-strict array ordering).
+ *
Use of this method requires the
+ * JSONassert library
+ * to be on the classpath.
+ * @param expectedJson the expected JSON content
+ * @see #json(String, boolean)
+ */
+ default BodyContentSpec json(String expectedJson) {
+ return json(expectedJson, false);
+ }
+
+ /**
+ * Parse the expected and actual response content as JSON and perform a
+ * comparison verifying that they contain the same attribute-value pairs
+ * regardless of formatting.
+ *
Can compare in two modes, depending on the {@code strict} parameter value:
+ *
+ * - {@code true}: strict checking. Not extensible and strict array ordering.
+ * - {@code false}: lenient checking. Extensible and non-strict array ordering.
+ *
+ * Use of this method requires the
* JSONassert library
- * on to be on the classpath.
- * @param expectedJson the expected JSON content.
+ * to be on the classpath.
+ * @param expectedJson the expected JSON content
+ * @param strict enables strict checking if {@code true}
+ * @since 5.3.16
+ * @see #json(String)
*/
- BodyContentSpec json(String expectedJson);
+ BodyContentSpec json(String expectedJson, boolean strict);
/**
* Parse expected and actual response content as XML and assert that
diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ErrorTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ErrorTests.java
index f2637bc1709..89a06defd64 100644
--- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ErrorTests.java
+++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ErrorTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2022 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.
@@ -37,13 +37,13 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Rossen Stoyanchev
* @since 5.0
*/
-public class ErrorTests {
+class ErrorTests {
private final WebTestClient client = WebTestClient.bindToController(new TestController()).build();
@Test
- public void notFound(){
+ void notFound(){
this.client.get().uri("/invalid")
.exchange()
.expectStatus().isNotFound()
@@ -51,7 +51,7 @@ public class ErrorTests {
}
@Test
- public void serverException() {
+ void serverException() {
this.client.get().uri("/server-error")
.exchange()
.expectStatus().isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR)
@@ -59,7 +59,7 @@ public class ErrorTests {
}
@Test // SPR-17363
- public void badRequestBeforeRequestBodyConsumed() {
+ void badRequestBeforeRequestBodyConsumed() {
EntityExchangeResult result = this.client.post()
.uri("/post")
.contentType(MediaType.APPLICATION_JSON)
diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ExchangeMutatorTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ExchangeMutatorTests.java
index d5dbbd597ce..759770bf652 100644
--- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ExchangeMutatorTests.java
+++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ExchangeMutatorTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2022 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.
@@ -18,7 +18,6 @@ package org.springframework.test.web.reactive.server.samples;
import java.security.Principal;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
@@ -37,23 +36,18 @@ import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
/**
* Samples tests that demonstrate applying ServerWebExchange initialization.
+ *
* @author Rossen Stoyanchev
*/
-public class ExchangeMutatorTests {
-
- private WebTestClient webTestClient;
+class ExchangeMutatorTests {
+ private final WebTestClient webTestClient = WebTestClient.bindToController(new TestController())
+ .apply(identity("Pablo"))
+ .build();
- @BeforeEach
- public void setUp() throws Exception {
-
- this.webTestClient = WebTestClient.bindToController(new TestController())
- .apply(identity("Pablo"))
- .build();
- }
@Test
- public void useGloballyConfiguredIdentity() throws Exception {
+ void useGloballyConfiguredIdentity() {
this.webTestClient.get().uri("/userIdentity")
.exchange()
.expectStatus().isOk()
@@ -61,8 +55,7 @@ public class ExchangeMutatorTests {
}
@Test
- public void useLocallyConfiguredIdentity() throws Exception {
-
+ void useLocallyConfiguredIdentity() {
this.webTestClient
.mutateWith(identity("Giovanni"))
.get().uri("/userIdentity")
diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/GlobalEntityResultConsumerTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/GlobalEntityResultConsumerTests.java
index 24bf92ecbb3..1a68d62ca1c 100644
--- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/GlobalEntityResultConsumerTests.java
+++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/GlobalEntityResultConsumerTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2021 the original author or authors.
+ * Copyright 2002-2022 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.
@@ -96,4 +96,5 @@ public class GlobalEntityResultConsumerTests {
return Arrays.asList(new Person("Joe"), new Person("Joseph"));
}
}
+
}
diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/HeaderAndCookieTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/HeaderAndCookieTests.java
index e42dff7c110..a2b743c6425 100644
--- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/HeaderAndCookieTests.java
+++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/HeaderAndCookieTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2022 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.
@@ -29,16 +29,17 @@ import org.springframework.web.bind.annotation.RestController;
/**
* Tests with headers and cookies.
+ *
* @author Rossen Stoyanchev
* @since 5.0
*/
-public class HeaderAndCookieTests {
+class HeaderAndCookieTests {
private final WebTestClient client = WebTestClient.bindToController(new TestController()).build();
@Test
- public void requestResponseHeaderPair() throws Exception {
+ void requestResponseHeaderPair() {
this.client.get().uri("/header-echo").header("h1", "in")
.exchange()
.expectStatus().isOk()
@@ -46,7 +47,7 @@ public class HeaderAndCookieTests {
}
@Test
- public void headerMultipleValues() throws Exception {
+ void headerMultipleValues() {
this.client.get().uri("/header-multi-value")
.exchange()
.expectStatus().isOk()
@@ -54,7 +55,7 @@ public class HeaderAndCookieTests {
}
@Test
- public void setCookies() {
+ void setCookies() {
this.client.get().uri("/cookie-echo")
.cookies(cookies -> cookies.add("k1", "v1"))
.exchange()
diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/JsonContentTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/JsonContentTests.java
index 82d271c8777..e6a4ed77995 100644
--- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/JsonContentTests.java
+++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/JsonContentTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2022 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.
@@ -31,10 +31,9 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.hamcrest.Matchers.containsString;
-
-
/**
* Samples of tests using {@link WebTestClient} with serialized JSON content.
*
@@ -42,47 +41,76 @@ import static org.hamcrest.Matchers.containsString;
* @author Sam Brannen
* @since 5.0
*/
-public class JsonContentTests {
+class JsonContentTests {
private final WebTestClient client = WebTestClient.bindToController(new PersonController()).build();
@Test
- public void jsonContent() {
+ void jsonContentWithDefaultLenientMode() {
+ this.client.get().uri("/persons")
+ .accept(MediaType.APPLICATION_JSON)
+ .exchange()
+ .expectStatus().isOk()
+ .expectBody().json(
+ "[{\"firstName\":\"Jane\"}," +
+ "{\"firstName\":\"Jason\"}," +
+ "{\"firstName\":\"John\"}]");
+ }
+
+ @Test
+ void jsonContentWithStrictMode() {
this.client.get().uri("/persons")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
- .expectBody().json("[{\"name\":\"Jane\"},{\"name\":\"Jason\"},{\"name\":\"John\"}]");
+ .expectBody().json(
+ "[{\"firstName\":\"Jane\",\"lastName\":\"Williams\"}," +
+ "{\"firstName\":\"Jason\",\"lastName\":\"Johnson\"}," +
+ "{\"firstName\":\"John\",\"lastName\":\"Smith\"}]",
+ true);
+ }
+
+ @Test
+ void jsonContentWithStrictModeAndMissingAttributes() {
+ assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> this.client.get().uri("/persons")
+ .accept(MediaType.APPLICATION_JSON)
+ .exchange()
+ .expectBody().json(
+ "[{\"firstName\":\"Jane\"}," +
+ "{\"firstName\":\"Jason\"}," +
+ "{\"firstName\":\"John\"}]",
+ true)
+ );
}
@Test
- public void jsonPathIsEqualTo() {
+ void jsonPathIsEqualTo() {
this.client.get().uri("/persons")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectBody()
- .jsonPath("$[0].name").isEqualTo("Jane")
- .jsonPath("$[1].name").isEqualTo("Jason")
- .jsonPath("$[2].name").isEqualTo("John");
+ .jsonPath("$[0].firstName").isEqualTo("Jane")
+ .jsonPath("$[1].firstName").isEqualTo("Jason")
+ .jsonPath("$[2].firstName").isEqualTo("John");
}
@Test
- public void jsonPathMatches() {
- this.client.get().uri("/persons/John")
+ void jsonPathMatches() {
+ this.client.get().uri("/persons/John/Smith")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectBody()
- .jsonPath("$.name").value(containsString("oh"));
+ .jsonPath("$.firstName").value(containsString("oh"));
}
@Test
- public void postJsonContent() {
+ void postJsonContent() {
this.client.post().uri("/persons")
.contentType(MediaType.APPLICATION_JSON)
- .bodyValue("{\"name\":\"John\"}")
+ .bodyValue("{\"firstName\":\"John\",\"lastName\":\"Smith\"}")
.exchange()
.expectStatus().isCreated()
.expectBody().isEmpty();
@@ -95,17 +123,38 @@ public class JsonContentTests {
@GetMapping
Flux getPersons() {
- return Flux.just(new Person("Jane"), new Person("Jason"), new Person("John"));
+ return Flux.just(new Person("Jane", "Williams"), new Person("Jason", "Johnson"), new Person("John", "Smith"));
}
- @GetMapping("/{name}")
- Person getPerson(@PathVariable String name) {
- return new Person(name);
+ @GetMapping("/{firstName}/{lastName}")
+ Person getPerson(@PathVariable String firstName, @PathVariable String lastName) {
+ return new Person(firstName, lastName);
}
@PostMapping
ResponseEntity savePerson(@RequestBody Person person) {
- return ResponseEntity.created(URI.create("/persons/" + person.getName())).build();
+ return ResponseEntity.created(URI.create(String.format("/persons/%s/%s", person.getFirstName(), person.getLastName()))).build();
+ }
+ }
+
+ static class Person {
+ private String firstName;
+ private String lastName;
+
+ public Person() {
+ }
+
+ public Person(String firstName, String lastName) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ public String getFirstName() {
+ return this.firstName;
+ }
+
+ public String getLastName() {
+ return this.lastName;
}
}
diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java
index 3acbf66d984..f1619d61881 100644
--- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java
+++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/ResponseEntityTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2022 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.
@@ -49,7 +49,7 @@ import static org.springframework.http.MediaType.TEXT_EVENT_STREAM;
* @author Rossen Stoyanchev
* @since 5.0
*/
-public class ResponseEntityTests {
+class ResponseEntityTests {
private final WebTestClient client = WebTestClient.bindToController(new PersonController())
.configureClient()
@@ -58,7 +58,7 @@ public class ResponseEntityTests {
@Test
- public void entity() {
+ void entity() {
this.client.get().uri("/John")
.exchange()
.expectStatus().isOk()
@@ -67,7 +67,7 @@ public class ResponseEntityTests {
}
@Test
- public void entityMatcher() {
+ void entityMatcher() {
this.client.get().uri("/John")
.exchange()
.expectStatus().isOk()
@@ -76,7 +76,7 @@ public class ResponseEntityTests {
}
@Test
- public void entityWithConsumer() {
+ void entityWithConsumer() {
this.client.get().uri("/John")
.exchange()
.expectStatus().isOk()
@@ -86,8 +86,7 @@ public class ResponseEntityTests {
}
@Test
- public void entityList() {
-
+ void entityList() {
List expected = Arrays.asList(
new Person("Jane"), new Person("Jason"), new Person("John"));
@@ -99,8 +98,7 @@ public class ResponseEntityTests {
}
@Test
- public void entityListWithConsumer() {
-
+ void entityListWithConsumer() {
this.client.get()
.exchange()
.expectStatus().isOk()
@@ -111,8 +109,7 @@ public class ResponseEntityTests {
}
@Test
- public void entityMap() {
-
+ void entityMap() {
Map map = new LinkedHashMap<>();
map.put("Jane", new Person("Jane"));
map.put("Jason", new Person("Jason"));
@@ -125,8 +122,7 @@ public class ResponseEntityTests {
}
@Test
- public void entityStream() {
-
+ void entityStream() {
FluxExchangeResult result = this.client.get()
.accept(TEXT_EVENT_STREAM)
.exchange()
@@ -143,7 +139,7 @@ public class ResponseEntityTests {
}
@Test
- public void postEntity() {
+ void postEntity() {
this.client.post()
.bodyValue(new Person("John"))
.exchange()
diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/XmlContentTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/XmlContentTests.java
index fef7d629a2b..c913d323522 100644
--- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/XmlContentTests.java
+++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/XmlContentTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2022 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.
@@ -40,15 +40,13 @@ import org.springframework.web.bind.annotation.RestController;
import static org.hamcrest.Matchers.startsWith;
-
-
/**
* Samples of tests using {@link WebTestClient} with XML content.
*
* @author Eric Deandrea
* @since 5.1
*/
-public class XmlContentTests {
+class XmlContentTests {
private static final String persons_XML =
""
@@ -63,7 +61,7 @@ public class XmlContentTests {
@Test
- public void xmlContent() {
+ void xmlContent() {
this.client.get().uri("/persons")
.accept(MediaType.APPLICATION_XML)
.exchange()
@@ -72,7 +70,7 @@ public class XmlContentTests {
}
@Test
- public void xpathIsEqualTo() {
+ void xpathIsEqualTo() {
this.client.get().uri("/persons")
.accept(MediaType.APPLICATION_XML)
.exchange()
@@ -88,7 +86,7 @@ public class XmlContentTests {
}
@Test
- public void xpathMatches() {
+ void xpathMatches() {
this.client.get().uri("/persons")
.accept(MediaType.APPLICATION_XML)
.exchange()
@@ -98,7 +96,7 @@ public class XmlContentTests {
}
@Test
- public void xpathContainsSubstringViaRegex() {
+ void xpathContainsSubstringViaRegex() {
this.client.get().uri("/persons/John")
.accept(MediaType.APPLICATION_XML)
.exchange()
@@ -108,8 +106,7 @@ public class XmlContentTests {
}
@Test
- public void postXmlContent() {
-
+ void postXmlContent() {
String content =
"" +
"John";