Print async result in Spring MVC Test ResultHandler

This commit is contained in:
Rossen Stoyanchev 2012-11-15 09:45:38 -05:00
parent f0f76e493d
commit 1f2e89e3ed
5 changed files with 60 additions and 7 deletions

View File

@ -110,9 +110,13 @@ class DefaultMvcResult implements MvcResult {
}
public Object getAsyncResult() {
return getAsyncResult(-1);
}
public Object getAsyncResult(long timeout) {
HttpServletRequest request = this.mockRequest;
if (request.isAsyncStarted()) {
if (!awaitAsyncResult(request)) {
if ((timeout != 0) && request.isAsyncStarted()) {
if (!awaitAsyncResult(request, timeout)) {
throw new IllegalStateException(
"Gave up waiting on async result from handler [" + this.handler + "] to complete");
}
@ -120,8 +124,10 @@ class DefaultMvcResult implements MvcResult {
return this.asyncResult;
}
private boolean awaitAsyncResult(HttpServletRequest request) {
long timeout = request.getAsyncContext().getTimeout();
private boolean awaitAsyncResult(HttpServletRequest request, long timeout) {
if (timeout != -1) {
timeout = request.getAsyncContext().getTimeout();
}
if (this.asyncResultLatch != null) {
try {
return this.asyncResultLatch.await(timeout, TimeUnit.MILLISECONDS);

View File

@ -85,4 +85,15 @@ public interface MvcResult {
*/
Object getAsyncResult();
/**
* Get the result of asynchronous execution or {@code null} if concurrent
* handling did not start. This method will wait for up to the given timeout
* for the completion of concurrent handling.
*
* @param timeout how long to wait for the async result to be set in
* milliseconds; if -1, the wait will be as long as the async timeout set
* on the Servlet request
*/
Object getAsyncResult(long timeout);
}

View File

@ -17,12 +17,18 @@
package org.springframework.test.web.servlet.result;
import java.util.Enumeration;
import java.util.Map;
import javax.servlet.ServletRequest;
import org.springframework.http.HttpHeaders;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultHandler;
import org.springframework.util.ClassUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.web.method.HandlerMethod;
@ -70,6 +76,11 @@ public class PrintingResultHandler implements ResultHandler {
this.printer.printHeading("Handler");
printHandler(result.getHandler(), result.getInterceptors());
if (ClassUtils.hasMethod(ServletRequest.class, "startAsync")) {
this.printer.printHeading("Async");
printAsyncResult(result);
}
this.printer.printHeading("Resolved Exception");
printResolvedException(result.getResolvedException());
@ -87,11 +98,11 @@ public class PrintingResultHandler implements ResultHandler {
protected void printRequest(MockHttpServletRequest request) throws Exception {
this.printer.printValue("HTTP Method", request.getMethod());
this.printer.printValue("Request URI", request.getRequestURI());
this.printer.printValue("Parameters", request.getParameterMap());
this.printer.printValue("Parameters", getParamsMultiValueMap(request));
this.printer.printValue("Headers", getRequestHeaders(request));
}
protected static HttpHeaders getRequestHeaders(MockHttpServletRequest request) {
protected final HttpHeaders getRequestHeaders(MockHttpServletRequest request) {
HttpHeaders headers = new HttpHeaders();
Enumeration<?> names = request.getHeaderNames();
while (names.hasMoreElements()) {
@ -104,6 +115,24 @@ public class PrintingResultHandler implements ResultHandler {
return headers;
}
protected final MultiValueMap<String, String> getParamsMultiValueMap(MockHttpServletRequest request) {
Map<String, String[]> params = request.getParameterMap();
MultiValueMap<String, String> multiValueMap = new LinkedMultiValueMap<String, String>();
for (String name : params.keySet()) {
if (params.get(name) != null) {
for (String value : params.get(name)) {
multiValueMap.add(name, value);
}
}
}
return multiValueMap;
}
protected void printAsyncResult(MvcResult result) throws Exception {
this.printer.printValue("Was async started", result.getRequest().isAsyncStarted());
this.printer.printValue("Async result", result.getAsyncResult(0));
}
/** Print the handler */
protected void printHandler(Object handler, HandlerInterceptor[] interceptors) throws Exception {
if (handler == null) {
@ -178,7 +207,7 @@ public class PrintingResultHandler implements ResultHandler {
this.printer.printValue("Cookies", response.getCookies());
}
protected static HttpHeaders getResponseHeaders(MockHttpServletResponse response) {
protected final HttpHeaders getResponseHeaders(MockHttpServletResponse response) {
HttpHeaders headers = new HttpHeaders();
for (String name : response.getHeaderNames()) {
headers.put(name, response.getHeaders(name));

View File

@ -124,4 +124,8 @@ public class StubMvcResult implements MvcResult {
return null;
}
public Object getAsyncResult(long timeout) {
return null;
}
}

View File

@ -17,6 +17,7 @@ package org.springframework.test.web.servlet.samples.standalone;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ -59,11 +60,13 @@ public class AsyncTests {
@Test
public void testCallable() throws Exception {
MvcResult mvcResult = this.mockMvc.perform(get("/1").param("callable", "true"))
.andDo(print())
.andExpect(request().asyncStarted())
.andExpect(request().asyncResult(new Person("Joe")))
.andReturn();
this.mockMvc.perform(asyncDispatch(mvcResult))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}"));