簡體   English   中英

用於DeferredResult的Spring MVC單元測試不會調用超時回調

[英]Spring MVC unit test for DeferredResult doesn't call timeout callback

我在Java 7上使用Spring 4.3.18和Spring Boot 1.5.14。

我正在實現一個RestController端點,該端點返回帶有超時回調的DeferredResult 我正在嘗試為超時回調編寫單元測試,但無法獲得MockMvc單元測試來調用超時回調。

為了進行測試,我編寫了以下端點:

@PostMapping("/test")
public DeferredResult<String>
testit() {
    logger.info("testit called");
    final DeferredResult<String> rv = new DeferredResult<>(1000L);
    rv.onTimeout(new Runnable() {
        @Override
        public void run() {
            logger.info("run called");
            rv.setResult("timed out");
        }
    });
    return rv;
}

和這個單元測試:

@Autowired
private MockMvc mockMvc;

@Test
public void testTest() throws Exception {
    MvcResult result = mockMvc.perform(post("/rest/tasks/test"))
        .andExpect(request().asyncStarted())
        .andReturn();
    result.getAsyncResult(1500);
    mockMvc.perform(asyncDispatch(result))
        .andExpect(status().isOk())
        ;
}

(對result.getAsyncResult(1500)的調用基於https://jira.spring.io/browse/SPR-16869

運行此命令時,將testit()端點,並且在1500 ms延遲后,我收到一個異常,抱怨從未調用過setResult() 超時處理程序未調用:

java.lang.IllegalStateException: Async result for handler [public org.springframework.web.context.request.async.DeferredResult<java.lang.String> my.package.TasksController.testit()] was not set during the specified timeToWait=1500
    at org.springframework.test.web.servlet.DefaultMvcResult.getAsyncResult(DefaultMvcResult.java:135)
    at my.package.TasksControllerTest.testTest(TasksControllerTest.java:200)
2517 [main] INFO my.package.TasksController - testit called

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /rest/tasks/test
       Parameters = {}
          Headers = {}

Handler:
             Type = my.package.TasksController
           Method = public org.springframework.web.context.request.async.DeferredResult<java.lang.String> my.package.TasksController.testit()

Async:
    Async started = true
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = {}
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []
4037 [Thread-2] INFO org.springframework.web.context.support.GenericWebApplicationContext - Closing org.springframework.web.context.support.GenericWebApplicationContext@6ea91f6: startup date [Thu Jul 26 19:44:31 EDT 2018]; root of context hierarchy

我需要做些什么才能使測試框架在DeferredResult上調用超時處理程序?

似乎可以在單元測試中創建一個合成超時,如下所示:

@Test
public void testTest() throws Exception {
    MvcResult result = mockMvc.perform(post("/rest/tasks/test"))
        .andExpect(request().asyncStarted())
        .andReturn();
    // Trigger a timeout on the request
    MockAsyncContext ctx = (MockAsyncContext) result.getRequest().getAsyncContext();
    for (AsyncListener listener : ctx.getListeners()) {
        listener.onTimeout(null);
    }
    mockMvc.perform(asyncDispatch(result))
        .andExpect(status().isOk())
        ;
}

訪問請求的異步偵聽器並調用onTimeout()將導致調用DeferredRequest的超時回調。

我的問題中對result.getAsyncResult(1500)的調用對該測試是多余的,因為asyncDispatch()仍將調用getAsyncResult()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM