Skip to content

Commit 1bc1df2

Browse files
committed
Polish client-side REST updates
Issue: SPR-11365
1 parent ca19920 commit 1bc1df2

File tree

4 files changed

+74
-38
lines changed

4 files changed

+74
-38
lines changed

spring-test/src/main/java/org/springframework/test/web/client/MockRestServiceServer.java

+19-18
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626
import org.springframework.http.client.ClientHttpRequestFactory;
2727
import org.springframework.http.client.ClientHttpResponse;
2828
import org.springframework.mock.http.client.MockAsyncClientHttpRequest;
29-
import org.springframework.test.web.client.match.MockRestRequestMatchers;
30-
import org.springframework.test.web.client.response.MockRestResponseCreators;
3129
import org.springframework.util.Assert;
3230
import org.springframework.web.client.AsyncRestTemplate;
3331
import org.springframework.web.client.RestTemplate;
@@ -46,7 +44,7 @@
4644
*
4745
* <pre class="code">
4846
* RestTemplate restTemplate = new RestTemplate()
49-
* MockRestServiceServer server = MockRestServiceServer.restTemplate(restTemplate).build();
47+
* MockRestServiceServer server = MockRestServiceServer.bindTo(restTemplate).build();
5048
*
5149
* server.expect(manyTimes(), requestTo("/hotels/42")).andExpect(method(HttpMethod.GET))
5250
* .andRespond(withSuccess("{ \"id\" : \"42\", \"name\" : \"Holiday Inn\"}", MediaType.APPLICATION_JSON));
@@ -125,56 +123,59 @@ public void verify() {
125123

126124

127125
/**
128-
* Build a {@code MockRestServiceServer} for a {@code RestTemplate}.
126+
* Return a builder for a {@code MockRestServiceServer} that should be used
127+
* to reply to the given {@code RestTemplate}.
129128
* @since 4.3
130129
*/
131-
public static MockRestServiceServerBuilder restTemplate(RestTemplate restTemplate) {
130+
public static MockRestServiceServerBuilder bindTo(RestTemplate restTemplate) {
132131
return new DefaultBuilder(restTemplate);
133132
}
134133

135134
/**
136-
* Build a {@code MockRestServiceServer} for an {@code AsyncRestTemplate}.
135+
* Return a builder for a {@code MockRestServiceServer} that should be used
136+
* to reply to the given {@code AsyncRestTemplate}.
137137
* @since 4.3
138138
*/
139-
public static MockRestServiceServerBuilder asyncRestTemplate(AsyncRestTemplate asyncRestTemplate) {
139+
public static MockRestServiceServerBuilder bindTo(AsyncRestTemplate asyncRestTemplate) {
140140
return new DefaultBuilder(asyncRestTemplate);
141141
}
142142

143143
/**
144-
* Build a {@code MockRestServiceServer} for a {@code RestGateway}.
144+
* Return a builder for a {@code MockRestServiceServer} that should be used
145+
* to reply to the given {@code RestGatewaySupport}.
145146
* @since 4.3
146147
*/
147-
public static MockRestServiceServerBuilder restGateway(RestGatewaySupport restGateway) {
148+
public static MockRestServiceServerBuilder bindTo(RestGatewaySupport restGateway) {
148149
Assert.notNull(restGateway, "'gatewaySupport' must not be null");
149150
return new DefaultBuilder(restGateway.getRestTemplate());
150151
}
151152

152153

153154
/**
154-
* A shortcut for {@code restTemplate(restTemplate).build()}.
155+
* A shortcut for {@code bindTo(restTemplate).build()}.
155156
* @param restTemplate the RestTemplate to set up for mock testing
156157
* @return the mock server
157158
*/
158159
public static MockRestServiceServer createServer(RestTemplate restTemplate) {
159-
return restTemplate(restTemplate).build();
160+
return bindTo(restTemplate).build();
160161
}
161162

162163
/**
163-
* A shortcut for {@code asyncRestTemplate(asyncRestTemplate).build()}.
164+
* A shortcut for {@code bindTo(asyncRestTemplate).build()}.
164165
* @param asyncRestTemplate the AsyncRestTemplate to set up for mock testing
165166
* @return the created mock server
166167
*/
167168
public static MockRestServiceServer createServer(AsyncRestTemplate asyncRestTemplate) {
168-
return asyncRestTemplate(asyncRestTemplate).build();
169+
return bindTo(asyncRestTemplate).build();
169170
}
170171

171172
/**
172-
* A shortcut for {@code restGateway(restGateway).build()}.
173+
* A shortcut for {@code bindTo(restGateway).build()}.
173174
* @param restGateway the REST gateway to set up for mock testing
174175
* @return the created mock server
175176
*/
176177
public static MockRestServiceServer createServer(RestGatewaySupport restGateway) {
177-
return restGateway(restGateway).build();
178+
return bindTo(restGateway).build();
178179
}
179180

180181

@@ -189,13 +190,13 @@ public interface MockRestServiceServerBuilder {
189190
* matching the order of declaration. This is a shortcut for:<br>
190191
* {@code builder.expectationManager(new UnorderedRequestExpectationManager)}
191192
*/
192-
MockRestServiceServerBuilder unordered();
193+
MockRestServiceServerBuilder ignoreExpectOrder();
193194

194195
/**
195196
* Configure a custom {@code RequestExpectationManager}.
196197
* <p>By default {@link SimpleRequestExpectationManager} is used. It is
197198
* also possible to switch to {@link UnorderedRequestExpectationManager}
198-
* by setting {@link #unordered()}.
199+
* by setting {@link #ignoreExpectOrder()}.
199200
*/
200201
MockRestServiceServerBuilder expectationManager(RequestExpectationManager manager);
201202

@@ -231,7 +232,7 @@ public DefaultBuilder(AsyncRestTemplate asyncRestTemplate) {
231232

232233

233234
@Override
234-
public MockRestServiceServerBuilder unordered() {
235+
public MockRestServiceServerBuilder ignoreExpectOrder() {
235236
expectationManager(new UnorderedRequestExpectationManager());
236237
return this;
237238
}

spring-test/src/test/java/org/springframework/test/web/client/samples/SampleTests.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.springframework.http.HttpMethod;
2424
import org.springframework.http.MediaType;
2525
import org.springframework.test.web.Person;
26-
import org.springframework.test.web.client.ExpectedCount;
2726
import org.springframework.test.web.client.MockRestServiceServer;
2827
import org.springframework.web.client.RestTemplate;
2928

@@ -50,7 +49,7 @@ public class SampleTests {
5049
@Before
5150
public void setup() {
5251
this.restTemplate = new RestTemplate();
53-
this.mockServer = MockRestServiceServer.createServer(this.restTemplate);
52+
this.mockServer = MockRestServiceServer.bindTo(this.restTemplate).ignoreExpectOrder().build();
5453
}
5554

5655
@Test

src/asciidoc/testing.adoc

+51-16
Original file line numberDiff line numberDiff line change
@@ -5045,28 +5045,63 @@ Here is an example:
50455045
----
50465046
RestTemplate restTemplate = new RestTemplate();
50475047
5048-
MockRestServiceServer mockServer = MockRestServiceServer.restTemplate(restTemplate).build();
5049-
mockServer.expect(manyTimes(), requestTo("/greeting"))
5050-
.andRespond(withSuccess("Hello world", MediaType.TEXT_PLAIN));
5048+
MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
5049+
mockServer.expect(requestTo("/greeting")).andRespond(withSuccess());
50515050
50525051
// Test code that uses the above RestTemplate ...
50535052
50545053
mockServer.verify();
50555054
----
50565055

5057-
In the above example, `MockRestServiceServer` -- the central class for client-side REST
5058-
tests -- configures the `RestTemplate` with a custom `ClientHttpRequestFactory` that
5056+
In the above example, `MockRestServiceServer`, the central class for client-side REST
5057+
tests, configures the `RestTemplate` with a custom `ClientHttpRequestFactory` that
50595058
asserts actual requests against expectations and returns "stub" responses. In this case
5060-
we expect a single request to "/greeting" and want to return a 200 response with
5061-
"text/plain" content. We could define as many additional requests and stub responses as
5062-
necessary. Once expected requests and stub responses have been defined, the `RestTemplate` can be
5063-
used in client-side code as usual. At the end of the tests `mockServer.verify()` can be
5064-
used to verify that all expected requests were performed.
5065-
5066-
The client-side test support also provides an alternative `ClientHttpRequestFactory`
5067-
strategy for executing requests with a `MockMvc` instance. That allows you to
5068-
process requests using your server-side code but without running a server.
5069-
Here is an example:
5059+
we expect a request to "/greeting" and want to return a 200 response with
5060+
"text/plain" content. We could define as additional expected requests and stub responses as
5061+
needed. When expected requests and stub responses are defined, the `RestTemplate` can be
5062+
used in client-side code as usual. At the end of testing `mockServer.verify()` can be
5063+
used to verify that all expectations have been satisfied.
5064+
5065+
By default requests are expected in the order in which expectations were declared.
5066+
You can set the `ignoreExpectOrder` option when building the server in which case
5067+
all expectations are checked (in order) to find a match for a given request. That
5068+
means requests are allowed to come in any order. Here is an example:
5069+
5070+
[source,java,indent=0]
5071+
[subs="verbatim,quotes"]
5072+
----
5073+
server = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder().build();
5074+
----
5075+
5076+
Even with unordered requests by default each request is allowed to execute once only.
5077+
The `expect` method provides an overloaded variant that accepts an `ExpectedCount`
5078+
argument that specifies a count range, e.g. `once`, `manyTimes`, `max`, `min`,
5079+
`between`, and so on. Here is an example:
5080+
5081+
[source,java,indent=0]
5082+
[subs="verbatim,quotes"]
5083+
----
5084+
RestTemplate restTemplate = new RestTemplate();
5085+
5086+
MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
5087+
mockServer.expect(times(2), requestTo("/foo")).andRespond(withSuccess());
5088+
mockServer.expect(times(3), requestTo("/bar")).andRespond(withSuccess());
5089+
5090+
// ...
5091+
5092+
mockServer.verify();
5093+
----
5094+
5095+
Note that when `ignoreExpectOrder` is not set (the default), and therefore requests
5096+
are expected in order of declaration, then that order only applies to the first of
5097+
any expected request. For example if "/foo" is expected 2 times followed by "/bar"
5098+
3 times, then there should be a request to "/foo" before there is a request to "/bar"
5099+
but aside from that subsequent "/foo" and "/bar" requests can come at any time.
5100+
5101+
As an alternative to all of the above the client-side test support also provides a
5102+
`ClientHttpRequestFactory` implementation that can be configured into a `RestTemplate`
5103+
to bind it to a `MockMvc` instance. That allows processing requests using actual
5104+
server-side logic but without running a server. Here is an example:
50705105

50715106
[source,java,indent=0]
50725107
[subs="verbatim,quotes"]
@@ -5086,7 +5121,7 @@ Here is an example:
50865121
Just like with server-side tests, the fluent API for client-side tests requires a few
50875122
static imports. Those are easy to find by searching __"MockRest*"__. Eclipse users
50885123
should add `"MockRestRequestMatchers.{asterisk}"` and `"MockRestResponseCreators.{asterisk}"`
5089-
as "favorite static members" in the Eclipse preferences under
5124+
as "favorite static members" in the Eclipse preferences under
50905125
__Java -> Editor -> Content Assist -> Favorites__.
50915126
That allows using content assist after typing the first character of the
50925127
static method name. Other IDEs (e.g. IntelliJ) may not require any additional

src/asciidoc/whats-new.adoc

+3-2
Original file line numberDiff line numberDiff line change
@@ -678,5 +678,6 @@ Spring 4.3 also improves the caching abstraction as follows:
678678
* The JUnit support in the _Spring TestContext Framework_ now requires JUnit 4.12 or higher.
679679
* Server-side Spring MVC Test supports expectations on response headers with multiple values.
680680
* Server-side Spring MVC Test parses form data request content and populates request parameters.
681-
* Client-side Spring MVC Test supports expected count of request executions (once, manyTimes, min, max, etc.)
682-
* Client-side Spring MVC Test supports expectations for form data in the request body.
681+
* Client-side REST test support allows indicating how many times a request is expected and
682+
whether the oder of declaration for expectations should be ignored (see <<spring-mvc-test-client>>)
683+
* Client-side REST Test supports expectations for form data in the request body.

0 commit comments

Comments
 (0)