从一段时间以前,我正在按照Spring博客实施长轮询.
这里我的转换方法具有与以前相同的响应签名,但它现在使用长轮询而不是立即响应:
private Map>> requests = new ConcurrentHashMap<>(); @RequestMapping(value = "/{uuid}", method = RequestMethod.GET) public DeferredResult > poll(@PathVariable("uuid") final String uuid) { // Create & store a new instance ResponseEntity> pendingOnTimeout = ResponseEntity.accepted().build(); DeferredResult > deferredResult = new DeferredResult<>(TWENTYFIVE_SECONDS, pendingOnTimeout); requests.put(uuid, deferredResult); // Clean up poll requests when done deferredResult.onCompletion(() -> { requests.remove(deferredResult); }); // Set result if already available Task task = taskHolder.retrieve(uuid); if (task == null) deferredResult.setResult(ResponseEntity.status(HttpStatus.GONE).build()); else // Done (or canceled): Redirect to retrieve file contents if (task.getFutureFile().isDone()) deferredResult.setResult(ResponseEntity.created(RetrieveController.uri(uuid)).build()); // Return result return deferredResult; }
特别是pendingOnTimeout
当请求花费太长时间(我之前立即返回)时,我想返回响应,以防止代理切断请求.
现在我觉得我已经按原样运行,但是我想编写一个证明这一点的单元测试.但是,我使用MockMvc(通过webAppContextSetup)的所有尝试都无法为我提供断言我得到accepted
标题的方法.例如,当我尝试以下内容时:
@Test public void pollPending() throws Exception { MvcResult result = mockMvc.perform(get("/poll/{uuid}", uuidPending)).andReturn(); mockMvc.perform(asyncDispatch(result)) .andExpect(status().isAccepted()); }
我得到以下stacktrace:
java.lang.IllegalStateException:处理程序[public org.springframework.web.context.request.async.DeferredResult> nl.bioprodict.blast.api.PollController.poll(java.lang.String)]的异步结果未在org.springframework.test.web上org.springframework.test.web.servlet.DefaultMvcResult.getAsyncResult(DefaultMvcResult.java:143)的org.springframework.util.Assert.state(Assert.java:392)中指定的timeToWait = 25000 org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch(MockMvcRequestBuilders.java:235)中的.servlet.DefaultMvcResult.getAsyncResult(DefaultMvcResult.java:120)at nl.bioprodict.blast.docs.PollControllerDocumentation.pollPending(PollControllerDocumentation) .java:53)...
与此相关的Spring框架测试,我发现它似乎都使用模拟它似乎:https://github.com/spring-projects/spring-framework/blob/master/spring-web/src/test/java/org/springframework /web/context/request/async/WebAsyncManagerTimeoutTests.java
如何测试DeferredResult timeoutResult的正确处理?
在我的情况下,在通过spring源代码并设置超时(10000毫秒)并获得异步结果后,我就解决了它,as;
mvcResult.getRequest().getAsyncContext().setTimeout(10000); mvcResult.getAsyncResult();
我的整个测试代码是;
MvcResult mvcResult = this.mockMvc.perform( post("") .contentType(MediaType.APPLICATION_JSON) .content( )) ***.andExpect(request().asyncStarted())*** .andReturn(); ***mvcResult.getRequest().getAsyncContext().setTimeout(10000);*** ***mvcResult.getAsyncResult();*** this.mockMvc .perform(asyncDispatch(mvcResult)) .andDo(print()) .andExpect(status().isOk());
希望能帮助到你..