Introduce MockRestServiceServer builder

MockRestServiceServer now provides static methods for builder-style
creation of MockRestServiceServer. This includes an option ignore
the order of declaration expected requests.

Issue: SPR-11365
This commit is contained in:
Rossen Stoyanchev 2016-02-23 07:20:15 -05:00
parent f58ef24efd
commit a56c69c9ca
5 changed files with 134 additions and 67 deletions

View File

@ -48,12 +48,10 @@ public abstract class AbstractRequestExpectationManager implements RequestExpect
} }
@Override
public List<RequestExpectation> getExpectations() { public List<RequestExpectation> getExpectations() {
return this.expectations; return this.expectations;
} }
@Override
public List<ClientHttpRequest> getRequests() { public List<ClientHttpRequest> getRequests() {
return this.requests; return this.requests;
} }

View File

@ -18,7 +18,6 @@ package org.springframework.test.web.client;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.List;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.client.AsyncClientHttpRequest; import org.springframework.http.client.AsyncClientHttpRequest;
@ -96,69 +95,25 @@ import org.springframework.web.client.support.RestGatewaySupport;
*/ */
public class MockRestServiceServer { public class MockRestServiceServer {
private RequestExpectationManager expectationManager = new OrderedRequestExpectationManager(); private final RequestExpectationManager expectationManager;
/** /**
* Private constructor. * Private constructor.
* @see #createServer(RestTemplate) * See static builder methods and {@code createServer} shortcut methods.
* @see #createServer(RestGatewaySupport)
*/ */
private MockRestServiceServer() { private MockRestServiceServer() {
} this.expectationManager = new SimpleRequestExpectationManager();
/**
* Create a {@code MockRestServiceServer} and set up the given
* {@code RestTemplate} with a mock {@link ClientHttpRequestFactory}.
* @param restTemplate the RestTemplate to set up for mock testing
* @return the created mock server
*/
public static MockRestServiceServer createServer(RestTemplate restTemplate) {
Assert.notNull(restTemplate, "'restTemplate' must not be null");
MockRestServiceServer mockServer = new MockRestServiceServer();
MockClientHttpRequestFactory factory = mockServer.new MockClientHttpRequestFactory();
restTemplate.setRequestFactory(factory);
return mockServer;
} }
/** /**
* Create a {@code MockRestServiceServer} and set up the given * Private constructor with {@code RequestExpectationManager}.
* {@code AsyRestTemplate} with a mock {@link AsyncClientHttpRequestFactory}. * See static builder methods and {@code createServer} shortcut methods.
* @param asyncRestTemplate the AsyncRestTemplate to set up for mock testing
* @return the created mock server
*/ */
public static MockRestServiceServer createServer(AsyncRestTemplate asyncRestTemplate) { private MockRestServiceServer(RequestExpectationManager expectationManager) {
Assert.notNull(asyncRestTemplate, "'asyncRestTemplate' must not be null"); this.expectationManager = expectationManager;
MockRestServiceServer mockServer = new MockRestServiceServer();
MockClientHttpRequestFactory factory = mockServer.new MockClientHttpRequestFactory();
asyncRestTemplate.setAsyncRequestFactory(factory);
return mockServer;
} }
/**
* Create a {@code MockRestServiceServer} and set up the given
* {@code RestGatewaySupport} with a mock {@link ClientHttpRequestFactory}.
* @param restGateway the REST gateway to set up for mock testing
* @return the created mock server
*/
public static MockRestServiceServer createServer(RestGatewaySupport restGateway) {
Assert.notNull(restGateway, "'gatewaySupport' must not be null");
return createServer(restGateway.getRestTemplate());
}
/**
* When this option is set, the order in which requests are executed does not
* need to match the order in which expected requests are declared.
*/
public MockRestServiceServer setIgnoreRequestOrder() {
String message = "Cannot switch to unordered mode after actual requests are made.";
Assert.state(this.expectationManager.getRequests().isEmpty(), message);
List<RequestExpectation> expectations = this.expectationManager.getExpectations();
this.expectationManager = new UnorderedRequestExpectationManager(expectations);
return this;
}
/** /**
* Set up a new HTTP request expectation. The returned {@link ResponseActions} * Set up a new HTTP request expectation. The returned {@link ResponseActions}
@ -183,6 +138,131 @@ public class MockRestServiceServer {
} }
/**
* Build a {@code MockRestServiceServer} with a {@code RestTemplate}.
* @since 4.3
*/
public static MockRestServiceServerBuilder restTemplate(RestTemplate restTemplate) {
return new DefaultBuilder(restTemplate);
}
/**
* Build a {@code MockRestServiceServer} with an {@code AsyncRestTemplate}.
* @since 4.3
*/
public static MockRestServiceServerBuilder asyncRestTemplate(AsyncRestTemplate asyncRestTemplate) {
return new DefaultBuilder(asyncRestTemplate);
}
/**
* Build a {@code MockRestServiceServer} with a {@code RestGateway}.
* @since 4.3
*/
public static MockRestServiceServerBuilder restGateway(RestGatewaySupport restGateway) {
Assert.notNull(restGateway, "'gatewaySupport' must not be null");
return new DefaultBuilder(restGateway.getRestTemplate());
}
/**
* A shortcut for {@code restTemplate(restTemplate).build()}.
* @param restTemplate the RestTemplate to set up for mock testing
* @return the mock server
*/
public static MockRestServiceServer createServer(RestTemplate restTemplate) {
return restTemplate(restTemplate).build();
}
/**
* A shortcut for {@code asyncRestTemplate(asyncRestTemplate).build()}.
* @param asyncRestTemplate the AsyncRestTemplate to set up for mock testing
* @return the created mock server
*/
public static MockRestServiceServer createServer(AsyncRestTemplate asyncRestTemplate) {
return asyncRestTemplate(asyncRestTemplate).build();
}
/**
* A shortcut for {@code restGateway(restGateway).build()}.
* @param restGateway the REST gateway to set up for mock testing
* @return the created mock server
*/
public static MockRestServiceServer createServer(RestGatewaySupport restGateway) {
return restGateway(restGateway).build();
}
/**
* Builder to create a {@code MockRestServiceServer}.
*/
public interface MockRestServiceServerBuilder {
/**
* When this option is set, requests can be executed in any order, i.e.
* not matching the order in which expected requests are declared.
*/
MockRestServiceServerBuilder ignoreExpectOrder();
/**
* Build the {@code MockRestServiceServer} and setting up the underlying
* {@code RestTemplate} or {@code AsyncRestTemplate} with a
* {@link ClientHttpRequestFactory} that creates mock requests.
*/
MockRestServiceServer build();
}
private static class DefaultBuilder implements MockRestServiceServerBuilder {
private final RestTemplate restTemplate;
private final AsyncRestTemplate asyncRestTemplate;
private boolean ignoreExpectOrder;
public DefaultBuilder(RestTemplate restTemplate) {
Assert.notNull(restTemplate, "'restTemplate' must not be null");
this.restTemplate = restTemplate;
this.asyncRestTemplate = null;
}
public DefaultBuilder(AsyncRestTemplate asyncRestTemplate) {
Assert.notNull(asyncRestTemplate, "'asyncRestTemplate' must not be null");
this.restTemplate = null;
this.asyncRestTemplate = asyncRestTemplate;
}
@Override
public MockRestServiceServerBuilder ignoreExpectOrder() {
this.ignoreExpectOrder = true;
return this;
}
@Override
public MockRestServiceServer build() {
MockRestServiceServer server = (this.ignoreExpectOrder ?
new MockRestServiceServer(new UnorderedRequestExpectationManager()) :
new MockRestServiceServer());
MockClientHttpRequestFactory factory = server.new MockClientHttpRequestFactory();
if (this.restTemplate != null) {
this.restTemplate.setRequestFactory(factory);
}
if (this.asyncRestTemplate != null) {
this.asyncRestTemplate.setAsyncRequestFactory(factory);
}
return server;
}
}
/** /**
* Mock ClientHttpRequestFactory that creates requests by iterating * Mock ClientHttpRequestFactory that creates requests by iterating
* over the list of expected {@link DefaultResponseActions}'s. * over the list of expected {@link DefaultResponseActions}'s.

View File

@ -16,7 +16,6 @@
package org.springframework.test.web.client; package org.springframework.test.web.client;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.ClientHttpResponse;
@ -31,16 +30,6 @@ import org.springframework.http.client.ClientHttpResponse;
*/ */
public interface RequestExpectationManager { public interface RequestExpectationManager {
/**
* Return the list of declared request expectations.
*/
List<RequestExpectation> getExpectations();
/**
* Return the list of actual requests.
*/
List<ClientHttpRequest> getRequests();
/** /**
* Set up a new request expectation. The returned {@link ResponseActions} is * Set up a new request expectation. The returned {@link ResponseActions} is
* used to add more expectations and define a response. * used to add more expectations and define a response.

View File

@ -30,7 +30,7 @@ import org.springframework.http.client.ClientHttpResponse;
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 4.3 * @since 4.3
*/ */
public class OrderedRequestExpectationManager extends AbstractRequestExpectationManager { public class SimpleRequestExpectationManager extends AbstractRequestExpectationManager {
private Iterator<RequestExpectation> iterator; private Iterator<RequestExpectation> iterator;

View File

@ -36,7 +36,7 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat
*/ */
public class OrderedRequestExpectationManagerTests { public class OrderedRequestExpectationManagerTests {
private OrderedRequestExpectationManager manager = new OrderedRequestExpectationManager(); private SimpleRequestExpectationManager manager = new SimpleRequestExpectationManager();
@Test @Test