【发布时间】:2016-03-24 10:21:26
【问题描述】:
我正在实施long polling as per the Spring blog from some time ago。
这里我转换的方法与以前的响应签名相同,但不是立即响应,而是现在使用长轮询:
private Map<String, DeferredResult<ResponseEntity<?>>> requests = new ConcurrentHashMap<>();
@RequestMapping(value = "/{uuid}", method = RequestMethod.GET)
public DeferredResult<ResponseEntity<?>> poll(@PathVariable("uuid") final String uuid) {
// Create & store a new instance
ResponseEntity<?> pendingOnTimeout = ResponseEntity.accepted().build();
DeferredResult<ResponseEntity<?>> 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());
}
我得到以下堆栈跟踪:
java.lang.IllegalStateException: 处理程序 [public org.springframework.web.context.request.async.DeferredResult> nl.bioprodict.blast.api.PollController.poll(java.lang.String)] 的异步结果不是在指定时间内设置ToWait=25000 在 org.springframework.util.Assert.state(Assert.java:392) 在 org.springframework.test.web.servlet.DefaultMvcResult.getAsyncResult(DefaultMvcResult.java:143) 在 org.springframework.test.web.servlet.DefaultMvcResult.getAsyncResult(DefaultMvcResult.java:120) 在 org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch(MockMvcRequestBuilders.java:235) 在 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-restdocs-mockmvc中测试它。 -
我刚刚遇到了同样的问题。您是否找到了允许在 DeferredResults 上测试超时的解决方案?
-
@John 不,还没有,虽然我现在已经停止寻找了。如果你找到任何东西,请告诉我!
-
@Tim 我需要测试同样的情况,你能找到解决方案吗?
-
@Tim,我刚刚收到同样的错误,原因是
DeferredResult中的引用是null。希望对您有所帮助。
标签: spring-mvc spring-mvc-test spring-web