Skip to content

Commit 89ca8e6

Browse files
committed
Document how to discard response body with WebTestClient
This commit better documents the ways to discard the response body with `WebTestClient`. Closes gh-35953
1 parent 7353ab4 commit 89ca8e6

File tree

14 files changed

+616
-302
lines changed

14 files changed

+616
-302
lines changed

framework-docs/modules/ROOT/pages/testing/resttestclient.adoc

Lines changed: 24 additions & 301 deletions
Large diffs are not rendered by default.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2025-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.docs.testing.resttestclient.assertj;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import org.springframework.http.MediaType;
22+
import org.springframework.test.web.servlet.client.ExchangeResult;
23+
import org.springframework.test.web.servlet.client.RestTestClient;
24+
import org.springframework.test.web.servlet.client.assertj.RestTestClientResponse;
25+
26+
import static org.assertj.core.api.Assertions.assertThat;
27+
28+
public class AssertJTests {
29+
30+
RestTestClient client;
31+
32+
@Test
33+
void withSpec() {
34+
// tag::withSpec[]
35+
RestTestClient.ResponseSpec spec = client.get().uri("/persons").exchange();
36+
37+
RestTestClientResponse response = RestTestClientResponse.from(spec);
38+
assertThat(response).hasStatusOk();
39+
assertThat(response).hasContentTypeCompatibleWith(MediaType.TEXT_PLAIN);
40+
// end::withSpec[]
41+
}
42+
43+
@Test
44+
void withResult() {
45+
// tag::withResult[]
46+
ExchangeResult result = client.get().uri("/persons").exchange().returnResult();
47+
48+
RestTestClientResponse response = RestTestClientResponse.from(result);
49+
assertThat(response).hasStatusOk();
50+
assertThat(response).hasContentTypeCompatibleWith(MediaType.TEXT_PLAIN);
51+
// end::withResult[]
52+
}
53+
54+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2025-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.docs.testing.resttestclient.contextconfig;
18+
19+
import org.junit.jupiter.api.BeforeEach;
20+
21+
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
22+
import org.springframework.test.web.servlet.client.RestTestClient;
23+
import org.springframework.web.context.WebApplicationContext;
24+
25+
26+
@SpringJUnitConfig(WebConfig.class) // Specify the configuration to load
27+
public class RestClientContextTests {
28+
29+
RestTestClient client;
30+
31+
@BeforeEach
32+
void setUp(WebApplicationContext context) { // Inject the configuration
33+
// Create the `RestTestClient`
34+
client = RestTestClient.bindToApplicationContext(context).build();
35+
}
36+
37+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright 2025-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.docs.testing.resttestclient.contextconfig;
18+
19+
public class WebConfig {
20+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2025-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.docs.testing.resttestclient.json;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import org.springframework.test.web.servlet.client.RestTestClient;
22+
23+
public class JsonTests {
24+
25+
RestTestClient client;
26+
27+
@Test
28+
void jsonBody() {
29+
// tag::jsonBody[]
30+
client.get().uri("/persons/1")
31+
.exchange()
32+
.expectStatus().isOk()
33+
.expectBody()
34+
.json("{\"name\":\"Jane\"}");
35+
// end::jsonBody[]
36+
}
37+
38+
@Test
39+
void jsonPath() {
40+
// tag::jsonPath[]
41+
client.get().uri("/persons")
42+
.exchange()
43+
.expectStatus().isOk()
44+
.expectBody()
45+
.jsonPath("$[0].name").isEqualTo("Jane")
46+
.jsonPath("$[1].name").isEqualTo("Jason");
47+
// end::jsonPath[]
48+
}
49+
50+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2025-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.docs.testing.resttestclient.nocontent;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import org.springframework.test.web.servlet.client.RestTestClient;
22+
23+
public class NoContentTests {
24+
25+
26+
RestTestClient client;
27+
28+
@Test
29+
void emptyBody() {
30+
Person person = new Person("Jane");
31+
// tag::emptyBody[]
32+
client.post().uri("/persons")
33+
.body(person)
34+
.exchange()
35+
.expectStatus().isCreated()
36+
.expectBody().isEmpty();
37+
// end::emptyBody[]
38+
}
39+
40+
@Test
41+
void ignoreBody() {
42+
Person person = new Person("Jane");
43+
// tag::ignoreBody[]
44+
client.post().uri("/persons")
45+
.body(person)
46+
.exchange()
47+
.expectStatus().isCreated()
48+
.expectBody(Void.class);
49+
// end::ignoreBody[]
50+
}
51+
52+
record Person(String name) {
53+
54+
}
55+
56+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright 2025-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.docs.testing.resttestclient.workflow;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import org.springframework.http.HttpHeaders;
22+
import org.springframework.http.MediaType;
23+
import org.springframework.test.web.servlet.client.EntityExchangeResult;
24+
import org.springframework.test.web.servlet.client.RestTestClient;
25+
26+
public class RestClientWorkflowTests {
27+
28+
RestTestClient client;
29+
30+
@Test
31+
void workflowTest() {
32+
// tag::test[]
33+
client.get().uri("/persons/1")
34+
.accept(MediaType.APPLICATION_JSON)
35+
.exchange()
36+
.expectStatus().isOk()
37+
.expectHeader().contentType(MediaType.APPLICATION_JSON)
38+
.expectBody();
39+
// end::test[]
40+
}
41+
42+
@Test
43+
void softAssertions() {
44+
// tag::soft-assertions[]
45+
client.get().uri("/persons/1")
46+
.accept(MediaType.APPLICATION_JSON)
47+
.exchange()
48+
.expectAll(
49+
spec -> spec.expectStatus().isOk(),
50+
spec -> spec.expectHeader().contentType(MediaType.APPLICATION_JSON)
51+
);
52+
// end::soft-assertions[]
53+
}
54+
55+
@Test
56+
void consumeWith() {
57+
// tag::consume[]
58+
client.get().uri("/persons/1")
59+
.exchange()
60+
.expectStatus().isOk()
61+
.expectBody(Person.class)
62+
.consumeWith(result -> {
63+
// custom assertions (for example, AssertJ)...
64+
});
65+
// end::consume[]
66+
}
67+
68+
@Test
69+
void returnResult() {
70+
// tag::result[]
71+
EntityExchangeResult<Person> result = client.get().uri("/persons/1")
72+
.exchange()
73+
.expectStatus().isOk()
74+
.expectBody(Person.class)
75+
.returnResult();
76+
77+
Person person = result.getResponseBody();
78+
HttpHeaders requestHeaders = result.getRequestHeaders();
79+
// end::result[]
80+
}
81+
82+
record Person(String name) {
83+
84+
}
85+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2025-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.docs.testing.resttestclient.assertj
18+
19+
import org.assertj.core.api.Assertions
20+
import org.junit.jupiter.api.Test
21+
import org.springframework.http.MediaType
22+
import org.springframework.test.web.servlet.client.RestTestClient
23+
import org.springframework.test.web.servlet.client.assertj.RestTestClientResponse
24+
25+
class AssertJTests {
26+
27+
28+
lateinit var client: RestTestClient
29+
30+
@Test
31+
fun withSpec() {
32+
// tag::withSpec[]
33+
val spec = client.get().uri("/persons").exchange()
34+
35+
val response = RestTestClientResponse.from(spec)
36+
Assertions.assertThat(response).hasStatusOk()
37+
Assertions.assertThat(response).hasContentTypeCompatibleWith(MediaType.TEXT_PLAIN)
38+
// end::withSpec[]
39+
}
40+
41+
@Test
42+
fun withResult() {
43+
// tag::withResult[]
44+
val result = client.get().uri("/persons").exchange().returnResult()
45+
46+
val response = RestTestClientResponse.from(result)
47+
Assertions.assertThat(response).hasStatusOk()
48+
Assertions.assertThat(response).hasContentTypeCompatibleWith(MediaType.TEXT_PLAIN)
49+
// end::withResult[]
50+
}
51+
52+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2025-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.docs.testing.resttestclient.contextconfig
18+
19+
import org.junit.jupiter.api.BeforeEach
20+
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig
21+
import org.springframework.test.web.servlet.client.RestTestClient
22+
import org.springframework.web.context.WebApplicationContext
23+
24+
@SpringJUnitConfig(WebConfig::class) // Specify the configuration to load
25+
class RestClientContextTests {
26+
27+
lateinit var client: RestTestClient
28+
29+
@BeforeEach
30+
fun setUp(context: WebApplicationContext) { // Inject the configuration
31+
// Create the `RestTestClient`
32+
client = RestTestClient.bindToApplicationContext(context).build()
33+
}
34+
}

0 commit comments

Comments
 (0)