Skip to content

Commit 20be40b

Browse files
committed
WebTestClient polish and minor refactoring
1 parent d924538 commit 20be40b

File tree

9 files changed

+390
-438
lines changed

9 files changed

+390
-438
lines changed

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

Lines changed: 100 additions & 161 deletions
Large diffs are not rendered by default.

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

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.springframework.http.HttpHeaders;
2525
import org.springframework.http.HttpMethod;
2626
import org.springframework.http.HttpStatus;
27+
import org.springframework.http.client.reactive.ClientHttpRequest;
2728
import org.springframework.web.reactive.function.client.ClientResponse;
2829

2930
import static org.springframework.web.reactive.function.BodyExtractors.toDataBuffers;
@@ -111,19 +112,16 @@ public T getResponseBody() {
111112

112113

113114
/**
114-
* Create an instance from a ClientResponse (body not yet consumed).
115+
* Create from ClientHttpRequest and ClientResponse (body not yet consumed).
115116
*/
116-
static ExchangeResult<Flux<DataBuffer>> fromResponse(HttpMethod method, URI url,
117-
HttpHeaders requestHeaders, ClientResponse response) {
118-
119-
HttpStatus status = response.statusCode();
120-
HttpHeaders responseHeaders = response.headers().asHttpHeaders();
121-
Flux<DataBuffer> body = response.body(toDataBuffers());
122-
return new ExchangeResult<>(method, url, requestHeaders, status, responseHeaders, body);
117+
static ExchangeResult<Flux<DataBuffer>> create(ClientHttpRequest request, ClientResponse response) {
118+
return new ExchangeResult<>(request.getMethod(), request.getURI(), request.getHeaders(),
119+
response.statusCode(), response.headers().asHttpHeaders(),
120+
response.body(toDataBuffers()));
123121
}
124122

125123
/**
126-
* Re-create the result with a generic type matching the decoded body.
124+
* Re-create with decoded body (possibly still not consumed).
127125
*/
128126
static <T> ExchangeResult<T> withDecodedBody(ExchangeResult<?> result, T body) {
129127
return new ExchangeResult<>(result.getMethod(), result.getUrl(), result.getRequestHeaders(),

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

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,74 +29,108 @@
2929
import static org.springframework.test.util.AssertionErrors.assertTrue;
3030

3131
/**
32-
* Provides methods for HTTP header assertions.
32+
* Assertions on headers of the response.
3333
*
3434
* @author Rossen Stoyanchev
3535
* @since 5.0
36-
* @see ResponseAssertions#header()
36+
* @see WebTestClient.ResponseSpec#expectHeader()
3737
*/
3838
public class HeaderAssertions {
3939

40-
private final HttpHeaders headers;
40+
private final ExchangeResult<?> exchangeResult;
4141

4242
private final WebTestClient.ResponseSpec responseSpec;
4343

4444

45-
public HeaderAssertions(HttpHeaders headers, WebTestClient.ResponseSpec responseSpec) {
46-
this.headers = headers;
45+
HeaderAssertions(ExchangeResult<?> exchangeResult, WebTestClient.ResponseSpec responseSpec) {
46+
this.exchangeResult = exchangeResult;
4747
this.responseSpec = responseSpec;
4848
}
4949

5050

51+
/**
52+
* Expect a header with the given name to match the specified values.
53+
*/
5154
public WebTestClient.ResponseSpec valueEquals(String headerName, String... values) {
52-
List<String> actual = this.headers.get(headerName);
55+
List<String> actual = getHeaders().get(headerName);
5356
assertEquals("Response header [" + headerName + "]", Arrays.asList(values), actual);
5457
return this.responseSpec;
5558
}
5659

60+
/**
61+
* Expect a header with the given name whose first value matches the
62+
* provided regex pattern.
63+
* @param headerName the header name
64+
* @param pattern String pattern to pass to {@link Pattern#compile(String)}
65+
*/
5766
public WebTestClient.ResponseSpec valueMatches(String headerName, String pattern) {
58-
List<String> values = this.headers.get(headerName);
67+
List<String> values = getHeaders().get(headerName);
5968
String value = CollectionUtils.isEmpty(values) ? "" : values.get(0);
6069
boolean match = Pattern.compile(pattern).matcher(value).matches();
6170
String message = "Response header " + headerName + "=\'" + value + "\' does not match " + pattern;
6271
assertTrue(message, match);
6372
return this.responseSpec;
6473
}
6574

66-
public WebTestClient.ResponseSpec cacheControlEquals(CacheControl cacheControl) {
67-
String actual = this.headers.getCacheControl();
75+
/**
76+
* Expect a "Cache-Control" header with the given value.
77+
*/
78+
public WebTestClient.ResponseSpec cacheControl(CacheControl cacheControl) {
79+
String actual = getHeaders().getCacheControl();
6880
assertEquals("Response header Cache-Control", cacheControl.getHeaderValue(), actual);
6981
return this.responseSpec;
7082
}
7183

72-
public WebTestClient.ResponseSpec contentDispositionEquals(ContentDisposition contentDisposition) {
73-
ContentDisposition actual = this.headers.getContentDisposition();
84+
/**
85+
* Expect a "Content-Disposition" header with the given value.
86+
*/
87+
public WebTestClient.ResponseSpec contentDisposition(ContentDisposition contentDisposition) {
88+
ContentDisposition actual = getHeaders().getContentDisposition();
7489
assertEquals("Response header Content-Disposition", contentDisposition, actual);
7590
return this.responseSpec;
7691
}
7792

78-
public WebTestClient.ResponseSpec contentLengthEquals(long contentLength) {
79-
long actual = this.headers.getContentLength();
93+
/**
94+
* Expect a "Content-Length" header with the given value.
95+
*/
96+
public WebTestClient.ResponseSpec contentLength(long contentLength) {
97+
long actual = getHeaders().getContentLength();
8098
assertEquals("Response header Content-Length", contentLength, actual);
8199
return this.responseSpec;
82100
}
83101

84-
public WebTestClient.ResponseSpec contentTypeEquals(MediaType mediaType) {
85-
MediaType actual = this.headers.getContentType();
102+
/**
103+
* Expect a "Content-Type" header with the given value.
104+
*/
105+
public WebTestClient.ResponseSpec contentType(MediaType mediaType) {
106+
MediaType actual = getHeaders().getContentType();
86107
assertEquals("Response header Content-Type", mediaType, actual);
87108
return this.responseSpec;
88109
}
89110

90-
public WebTestClient.ResponseSpec expiresEquals(int expires) {
91-
long actual = this.headers.getExpires();
111+
/**
112+
* Expect an "Expires" header with the given value.
113+
*/
114+
public WebTestClient.ResponseSpec expires(int expires) {
115+
long actual = getHeaders().getExpires();
92116
assertEquals("Response header Expires", expires, actual);
93117
return this.responseSpec;
94118
}
95119

96-
public WebTestClient.ResponseSpec lastModifiedEquals(int lastModified) {
97-
long actual = this.headers.getLastModified();
120+
/**
121+
* Expect a "Last-Modified" header with the given value.
122+
*/
123+
public WebTestClient.ResponseSpec lastModified(int lastModified) {
124+
long actual = getHeaders().getLastModified();
98125
assertEquals("Response header Last-Modified", lastModified, actual);
99126
return this.responseSpec;
100127
}
101128

129+
130+
// Private methods
131+
132+
private HttpHeaders getHeaders() {
133+
return this.exchangeResult.getResponseHeaders();
134+
}
135+
102136
}

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

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,22 @@
2020
import static org.springframework.test.util.AssertionErrors.assertEquals;
2121

2222
/**
23-
* Assertions on the status of a response.
23+
* Assertions on the response status.
2424
*
2525
* @author Rossen Stoyanchev
2626
* @since 5.0
27-
* @see ResponseAssertions#status()
27+
* @see WebTestClient.ResponseSpec#expectStatus()
2828
*/
2929
@SuppressWarnings("unused")
3030
public class StatusAssertions {
3131

32-
private final HttpStatus httpStatus;
32+
private final ExchangeResult<?> exchangeResult;
3333

3434
private final WebTestClient.ResponseSpec responseSpec;
3535

3636

37-
StatusAssertions(HttpStatus status, WebTestClient.ResponseSpec responseSpec) {
38-
this.httpStatus = status;
37+
StatusAssertions(ExchangeResult<?> exchangeResult, WebTestClient.ResponseSpec responseSpec) {
38+
this.exchangeResult = exchangeResult;
3939
this.responseSpec = responseSpec;
4040
}
4141

@@ -44,157 +44,172 @@ public class StatusAssertions {
4444
* Assert the response status as an {@link HttpStatus}.
4545
*/
4646
public WebTestClient.ResponseSpec isEqualTo(HttpStatus status) {
47-
assertEquals("Response status", status, this.httpStatus);
47+
assertEquals("Response status", status, getStatus());
4848
return this.responseSpec;
4949
}
5050

5151
/**
5252
* Assert the response status as an integer.
5353
*/
5454
public WebTestClient.ResponseSpec isEqualTo(int status) {
55-
assertEquals("Response status", status, this.httpStatus.value());
55+
assertEquals("Response status", status, getStatus().value());
5656
return this.responseSpec;
5757
}
5858

5959
/**
6060
* Assert the response status code is {@code HttpStatus.OK} (200).
6161
*/
6262
public WebTestClient.ResponseSpec isOk() {
63-
assertEquals("Status", HttpStatus.OK, this.httpStatus);
63+
assertEquals("Status", HttpStatus.OK, getStatus());
6464
return this.responseSpec;
6565
}
6666

6767
/**
6868
* Assert the response status code is {@code HttpStatus.CREATED} (201).
6969
*/
7070
public WebTestClient.ResponseSpec isCreated() {
71-
assertEquals("Status", HttpStatus.CREATED, this.httpStatus);
71+
assertEquals("Status", HttpStatus.CREATED, getStatus());
7272
return this.responseSpec;
7373
}
7474

7575
/**
7676
* Assert the response status code is {@code HttpStatus.ACCEPTED} (202).
7777
*/
7878
public WebTestClient.ResponseSpec isAccepted() {
79-
assertEquals("Status", HttpStatus.ACCEPTED, this.httpStatus);
79+
assertEquals("Status", HttpStatus.ACCEPTED, getStatus());
8080
return this.responseSpec;
8181
}
8282

8383
/**
8484
* Assert the response status code is {@code HttpStatus.NO_CONTENT} (204).
8585
*/
8686
public WebTestClient.ResponseSpec isNoContent() {
87-
assertEquals("Status", HttpStatus.NO_CONTENT, this.httpStatus);
87+
assertEquals("Status", HttpStatus.NO_CONTENT, getStatus());
8888
return this.responseSpec;
8989
}
9090

9191
/**
9292
* Assert the response status code is {@code HttpStatus.FOUND} (302).
9393
*/
9494
public WebTestClient.ResponseSpec isFound() {
95-
assertEquals("Status", HttpStatus.FOUND, this.httpStatus);
95+
assertEquals("Status", HttpStatus.FOUND, getStatus());
9696
return this.responseSpec;
9797
}
9898

9999
/**
100100
* Assert the response status code is {@code HttpStatus.SEE_OTHER} (303).
101101
*/
102102
public WebTestClient.ResponseSpec isSeeOther() {
103-
assertEquals("Status", HttpStatus.SEE_OTHER, this.httpStatus);
103+
assertEquals("Status", HttpStatus.SEE_OTHER, getStatus());
104104
return this.responseSpec;
105105
}
106106

107107
/**
108108
* Assert the response status code is {@code HttpStatus.NOT_MODIFIED} (304).
109109
*/
110110
public WebTestClient.ResponseSpec isNotModified() {
111-
assertEquals("Status", HttpStatus.NOT_MODIFIED, this.httpStatus);
111+
assertEquals("Status", HttpStatus.NOT_MODIFIED, getStatus());
112112
return this.responseSpec;
113113
}
114114

115115
/**
116116
* Assert the response status code is {@code HttpStatus.TEMPORARY_REDIRECT} (307).
117117
*/
118118
public WebTestClient.ResponseSpec isTemporaryRedirect() {
119-
assertEquals("Status", HttpStatus.TEMPORARY_REDIRECT, this.httpStatus);
119+
assertEquals("Status", HttpStatus.TEMPORARY_REDIRECT, getStatus());
120120
return this.responseSpec;
121121
}
122122

123123
/**
124124
* Assert the response status code is {@code HttpStatus.PERMANENT_REDIRECT} (308).
125125
*/
126126
public WebTestClient.ResponseSpec isPermanentRedirect() {
127-
assertEquals("Status", HttpStatus.PERMANENT_REDIRECT, this.httpStatus);
127+
assertEquals("Status", HttpStatus.PERMANENT_REDIRECT, getStatus());
128128
return this.responseSpec;
129129
}
130130

131131
/**
132132
* Assert the response status code is {@code HttpStatus.BAD_REQUEST} (400).
133133
*/
134134
public WebTestClient.ResponseSpec isBadRequest() {
135-
assertEquals("Status", HttpStatus.BAD_REQUEST, this.httpStatus);
135+
assertEquals("Status", HttpStatus.BAD_REQUEST, getStatus());
136+
return this.responseSpec;
137+
}
138+
139+
/**
140+
* Assert the response status code is {@code HttpStatus.UNAUTHORIZED} (401).
141+
*/
142+
public WebTestClient.ResponseSpec isUnauthorized() {
143+
assertEquals("Status", HttpStatus.UNAUTHORIZED, getStatus());
136144
return this.responseSpec;
137145
}
138146

139147
/**
140148
* Assert the response status code is {@code HttpStatus.NOT_FOUND} (404).
141149
*/
142150
public WebTestClient.ResponseSpec isNotFound() {
143-
assertEquals("Status", HttpStatus.NOT_FOUND, this.httpStatus);
151+
assertEquals("Status", HttpStatus.NOT_FOUND, getStatus());
144152
return this.responseSpec;
145153
}
146154

147155
/**
148156
* Assert the response error message.
149157
*/
150158
public WebTestClient.ResponseSpec reasonEquals(String reason) {
151-
assertEquals("Response status reason", reason, this.httpStatus.getReasonPhrase());
159+
assertEquals("Response status reason", reason, getStatus().getReasonPhrase());
152160
return this.responseSpec;
153161
}
154162

155163
/**
156164
* Assert the response status code is in the 1xx range.
157165
*/
158166
public WebTestClient.ResponseSpec is1xxInformational() {
159-
String message = "Range for response status value " + this.httpStatus;
160-
assertEquals(message, HttpStatus.Series.INFORMATIONAL, this.httpStatus.series());
167+
String message = "Range for response status value " + getStatus();
168+
assertEquals(message, HttpStatus.Series.INFORMATIONAL, getStatus().series());
161169
return this.responseSpec;
162170
}
163171

164172
/**
165173
* Assert the response status code is in the 2xx range.
166174
*/
167175
public WebTestClient.ResponseSpec is2xxSuccessful() {
168-
String message = "Range for response status value " + this.httpStatus;
169-
assertEquals(message, HttpStatus.Series.SUCCESSFUL, this.httpStatus.series());
176+
String message = "Range for response status value " + getStatus();
177+
assertEquals(message, HttpStatus.Series.SUCCESSFUL, getStatus().series());
170178
return this.responseSpec;
171179
}
172180

173181
/**
174182
* Assert the response status code is in the 3xx range.
175183
*/
176184
public WebTestClient.ResponseSpec is3xxRedirection() {
177-
String message = "Range for response status value " + this.httpStatus;
178-
assertEquals(message, HttpStatus.Series.REDIRECTION, this.httpStatus.series());
185+
String message = "Range for response status value " + getStatus();
186+
assertEquals(message, HttpStatus.Series.REDIRECTION, getStatus().series());
179187
return this.responseSpec;
180188
}
181189

182190
/**
183191
* Assert the response status code is in the 4xx range.
184192
*/
185193
public WebTestClient.ResponseSpec is4xxClientError() {
186-
String message = "Range for response status value " + this.httpStatus;
187-
assertEquals(message, HttpStatus.Series.CLIENT_ERROR, this.httpStatus.series());
194+
String message = "Range for response status value " + getStatus();
195+
assertEquals(message, HttpStatus.Series.CLIENT_ERROR, getStatus().series());
188196
return this.responseSpec;
189197
}
190198

191199
/**
192200
* Assert the response status code is in the 5xx range.
193201
*/
194202
public WebTestClient.ResponseSpec is5xxServerError() {
195-
String message = "Range for response status value " + this.httpStatus;
196-
assertEquals(message, HttpStatus.Series.SERVER_ERROR, this.httpStatus.series());
203+
String message = "Range for response status value " + getStatus();
204+
assertEquals(message, HttpStatus.Series.SERVER_ERROR, getStatus().series());
197205
return this.responseSpec;
198206
}
199207

208+
209+
// Private methods
210+
211+
private HttpStatus getStatus() {
212+
return this.exchangeResult.getStatus();
213+
}
214+
200215
}

0 commit comments

Comments
 (0)