提交 35543489 编写于 作者: K Kamill Sokol 提交者: Rossen Stoyanchev

Support custom HTTP verbs in Spring MVC Test

Prior to this commit, Spring MVC Test only supported HTTP methods GET,
POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE and multipart file
upload. This change adds generic methods to MockMvcRequestBuilders in
order to allow testing of arbitrary HTTP methods in a Spring MVC
application.

Issue: SPR-13719
上级 9e16cbda
......@@ -60,16 +60,20 @@ import org.springframework.web.util.UriUtils;
*
* <p>Application tests will typically access this builder through the static factory
* methods in {@link MockMvcRequestBuilders}.
* <p>Although this class cannot be extended, additional ways to initialize
* the {@code MockHttpServletRequest} can be plugged in via
* {@link #with(RequestPostProcessor)}.
*
* @author Rossen Stoyanchev
* @author Arjen Poutsma
* @author Sam Brannen
* @author Kamill Sokol
* @since 3.2
*/
public class MockHttpServletRequestBuilder
implements ConfigurableSmartRequestBuilder<MockHttpServletRequestBuilder>, Mergeable {
private final HttpMethod method;
private final String method;
private final URI url;
......@@ -109,37 +113,45 @@ public class MockHttpServletRequestBuilder
/**
* Package private constructor. To get an instance, use static factory
* methods in {@link MockMvcRequestBuilders}.
* <p>Although this class cannot be extended, additional ways to initialize
* the {@code MockHttpServletRequest} can be plugged in via
* {@link #with(RequestPostProcessor)}.
* @param httpMethod the HTTP method (GET, POST, etc)
* @param url a URL template; the resulting URL will be encoded
* @param vars zero or more URL variables
*/
MockHttpServletRequestBuilder(HttpMethod httpMethod, String url, Object... vars) {
this(httpMethod.name(), UriComponentsBuilder.fromUriString(url).buildAndExpand(vars).encode().toUri());
}
/**
* @param httpMethod the HTTP method (GET, POST, etc)
* @param url a URL template; the resulting URL will be encoded
* @param vars zero or more URL variables
* @since 4.3
*/
MockHttpServletRequestBuilder(String httpMethod, String url, Object... vars) {
this(httpMethod, UriComponentsBuilder.fromUriString(url).buildAndExpand(vars).encode().toUri());
}
/**
* Package private constructor. To get an instance, use static factory
* methods in {@link MockMvcRequestBuilders}.
* <p>Although this class cannot be extended, additional ways to initialize
* the {@code MockHttpServletRequest} can be plugged in via
* {@link #with(RequestPostProcessor)}.
* @param httpMethod the HTTP method (GET, POST, etc)
* @param url the URL
* @since 4.0.3
*/
MockHttpServletRequestBuilder(HttpMethod httpMethod, URI url) {
this(httpMethod.name(), url);
}
/**
* @param httpMethod the HTTP method (GET, POST, etc)
* @param url the URL
* @since 4.3
*/
MockHttpServletRequestBuilder(String httpMethod, URI url) {
Assert.notNull(httpMethod, "httpMethod is required");
Assert.notNull(url, "url is required");
this.method = httpMethod;
this.url = url;
}
/**
* Add a request parameter to the {@link MockHttpServletRequest}.
* <p>If called more than once, new values get added to existing ones.
......@@ -585,7 +597,7 @@ public class MockHttpServletRequestBuilder
request.setServerPort(this.url.getPort());
}
request.setMethod(this.method.name());
request.setMethod(this.method);
for (String name : this.headers.keySet()) {
for (Object value : this.headers.get(name)) {
......
......@@ -42,6 +42,7 @@ import org.springframework.test.web.servlet.RequestBuilder;
* @author Greg Turnquist
* @author Sebastien Deleuze
* @author Sam Brannen
* @author Kamill Sokol
* @since 3.2
*/
public abstract class MockMvcRequestBuilders {
......@@ -175,7 +176,7 @@ public abstract class MockMvcRequestBuilders {
/**
* Create a {@link MockHttpServletRequestBuilder} for a request with the given HTTP method.
* @param httpMethod the HTTP method
* @param httpMethod the HTTP method (GET, POST, etc)
* @param urlTemplate a URL template; the resulting URL will be encoded
* @param urlVariables zero or more URL variables
*/
......@@ -183,6 +184,17 @@ public abstract class MockMvcRequestBuilders {
return new MockHttpServletRequestBuilder(httpMethod, urlTemplate, urlVariables);
}
/**
* Create a {@link MockHttpServletRequestBuilder} for a request with the given HTTP method.
* @param httpMethod the HTTP method (GET, POST, etc)
* @param urlTemplate a URL template; the resulting URL will be encoded
* @param urlVariables zero or more URL variables
* @since 4.3
*/
public static MockHttpServletRequestBuilder request(String httpMethod, String urlTemplate, Object... urlVariables) {
return new MockHttpServletRequestBuilder(httpMethod, urlTemplate, urlVariables);
}
/**
* Create a {@link MockHttpServletRequestBuilder} for a request with the given HTTP method.
* @param httpMethod the HTTP method (GET, POST, etc)
......@@ -193,6 +205,16 @@ public abstract class MockMvcRequestBuilders {
return new MockHttpServletRequestBuilder(httpMethod, uri);
}
/**
* Create a {@link MockHttpServletRequestBuilder} for a request with the given HTTP method.
* @param httpMethod the HTTP method (GET, POST, etc)
* @param uri the URL
* @since 4.3
*/
public static MockHttpServletRequestBuilder request(String httpMethod, URI uri) {
return new MockHttpServletRequestBuilder(httpMethod, uri);
}
/**
* Create a {@link MockMultipartHttpServletRequestBuilder} for a multipart request.
* @param urlTemplate a URL template; the resulting URL will be encoded
......
......@@ -471,7 +471,9 @@ public class MockHttpServletRequestBuilderTests {
assertEquals(user, request.getUserPrincipal());
}
// SPR-12945
/**
* See SPR-12945
*/
@Test
public void mergeInvokesDefaultRequestPostProcessorFirst() {
final String ATTR = "ATTR";
......@@ -492,6 +494,24 @@ public class MockHttpServletRequestBuilderTests {
assertEquals(EXEPCTED, request.getAttribute(ATTR));
}
/**
* See SPR-13719
*/
@Test
public void arbitraryMethod() {
/*
* http method is case-sensitive
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.1
*/
String httpMethod = "REPort";
this.builder = new MockHttpServletRequestBuilder(httpMethod, "/foo/{bar}", 42);
MockHttpServletRequest request = this.builder.buildRequest(this.servletContext);
assertEquals(httpMethod, request.getMethod());
assertEquals("/foo/42", request.getPathInfo());
}
private final class User implements Principal {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册