From 3c4ec9026a172bc178b77d3e2e2e8724171cf294 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Fri, 3 Jul 2015 17:51:46 +0200 Subject: [PATCH] Introduce test for DeferredResult w/ delayed error in MVC Test This commit introduces a test that verifies the fix introduced in 6842fd7fb954e751fb6c310f7183527fd1876653. Issue: SPR-13079 --- .../samples/standalone/AsyncTests.java | 70 +++++++++++++++---- 1 file changed, 57 insertions(+), 13 deletions(-) diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java index 1b1f36bc6de..f516c351e79 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java @@ -24,6 +24,7 @@ import java.util.concurrent.CopyOnWriteArrayList; import org.junit.Test; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.test.web.Person; import org.springframework.test.web.servlet.MockMvc; @@ -31,12 +32,13 @@ import org.springframework.test.web.servlet.MvcResult; import org.springframework.ui.Model; import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFutureTask; +import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.request.async.DeferredResult; import static org.junit.Assert.*; - import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @@ -48,6 +50,7 @@ import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*; * @author Rossen Stoyanchev * @author Sebastien Deleuze * @author Sam Brannen + * @author Jacek Suchenia */ public class AsyncTests { @@ -84,8 +87,8 @@ public class AsyncTests { } @Test - public void deferredResultWithSetValue() throws Exception { - MvcResult mvcResult = this.mockMvc.perform(get("/1").param("deferredResultWithSetValue", "true")) + public void deferredResultWithImmediateValue() throws Exception { + MvcResult mvcResult = this.mockMvc.perform(get("/1").param("deferredResultWithImmediateValue", "true")) .andExpect(request().asyncStarted()) .andExpect(request().asyncResult(new Person("Joe"))) .andReturn(); @@ -96,6 +99,20 @@ public class AsyncTests { .andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}")); } + /** + * SPR-13079 + */ + @Test + public void deferredResultWithDelayedError() throws Exception { + MvcResult mvcResult = this.mockMvc.perform(get("/1").param("deferredResultWithDelayedError", "true")) + .andExpect(request().asyncStarted()) + .andReturn(); + + this.mockMvc.perform(asyncDispatch(mvcResult)) + .andExpect(status().is5xxServerError()) + .andExpect(content().string("Delayed Error")); + } + @Test public void listenableFuture() throws Exception { MvcResult mvcResult = this.mockMvc.perform(get("/1").param("listenableFuture", "true")) @@ -110,21 +127,25 @@ public class AsyncTests { .andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}")); } - @Test // SPR-12597 - public void completableFuture() throws Exception { - MvcResult mvcResult = this.mockMvc.perform(get("/1").param("completableFuture", "true")) + /** + * SPR-12597 + */ + @Test + public void completableFutureWithImmediateValue() throws Exception { + MvcResult mvcResult = this.mockMvc.perform(get("/1").param("completableFutureWithImmediateValue", "true")) .andExpect(request().asyncStarted()) .andReturn(); - this.asyncController.onMessage("Joe"); - this.mockMvc.perform(asyncDispatch(mvcResult)) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}")); } - @Test // SPR-12735 + /** + * SPR-12735 + */ + @Test public void printAsyncResult() throws Exception { StringWriter writer = new StringWriter(); @@ -171,13 +192,30 @@ public class AsyncTests { return deferredResult; } - @RequestMapping(params = "deferredResultWithSetValue") - public DeferredResult getDeferredResultWithSetValue() { + @RequestMapping(params = "deferredResultWithImmediateValue") + public DeferredResult getDeferredResultWithImmediateValue() { DeferredResult deferredResult = new DeferredResult(); deferredResult.setResult(new Person("Joe")); return deferredResult; } + @RequestMapping(params = "deferredResultWithDelayedError") + public DeferredResult getDeferredResultWithDelayedError() { + final DeferredResult deferredResult = new DeferredResult(); + new Thread() { + public void run() { + try { + Thread.sleep(100); + deferredResult.setErrorResult(new RuntimeException("Delayed Error")); + } + catch (InterruptedException e) { + /* no-op */ + } + } + }.start(); + return deferredResult; + } + @RequestMapping(params = "listenableFuture") public ListenableFuture getListenableFuture() { ListenableFutureTask futureTask = new ListenableFutureTask(() -> new Person("Joe")); @@ -185,13 +223,19 @@ public class AsyncTests { return futureTask; } - @RequestMapping(params = "completableFuture") - public CompletableFuture getCompletableFuture() { + @RequestMapping(params = "completableFutureWithImmediateValue") + public CompletableFuture getCompletableFutureWithImmediateValue() { CompletableFuture future = new CompletableFuture(); future.complete(new Person("Joe")); return future; } + @ExceptionHandler(Exception.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public String errorHandler(Exception e) { + return e.getMessage(); + } + public void onMessage(String name) { for (DeferredResult deferredResult : this.deferredResults) { deferredResult.setResult(new Person(name));