2015-12-17 23 views
9

Tôi đang triển khai long polling as per the Spring blog from some time ago.Cách kiểm tra thời gian chờ của DeferredResultResult

Ở đây phương pháp chuyển đổi của tôi với chữ ký phản ứng giống như trước, nhưng thay vì đáp ứng ngay lập tức, bây giờ nó sử dụng phiếu dài:

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; 
} 

Đặc biệt tôi muốn trả lại phản ứng pendingOnTimeout khi yêu cầu mất quá nhiều thời dài (mà tôi đã quay trở lại ngay trước đó), để ngăn các proxy cắt bỏ yêu cầu.

Bây giờ tôi nghĩ rằng tôi đã nhận được điều này làm việc như là, nhưng tôi muốn viết một unittest xác nhận điều này. Tuy nhiên tất cả các nỗ lực của tôi khi sử dụng MockMvc (thông qua webAppContextSetup) không cung cấp cho tôi một phương tiện để khẳng định rằng tôi nhận được một tiêu đề accepted. Khi tôi ví dụ thử như sau:

@Test 
public void pollPending() throws Exception { 
    MvcResult result = mockMvc.perform(get("/poll/{uuid}", uuidPending)).andReturn(); 
    mockMvc.perform(asyncDispatch(result)) 
      .andExpect(status().isAccepted()); 
} 

tôi nhận được stacktrace sau:

java.lang.IllegalStateException: Async kết quả cho handler [org.springframework.web.context.request.async công cộng .DeferredResult> nl.bioprodict.blast.api.PollController.poll (java.lang.String)] không được thiết lập trong timeToWait được chỉ định = 25000 tại org.springframework.util.Assert.state (Assert.java:392) tại org.springframework.test.web.servlet.DefaultMvcResult.getAsyncResult (DefaultMvcResult.java:143) tại org.springframework.test.web.servlet .DefaultMvcResult.getAsyncResult (DefaultMvcResult.java:120) tại org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch (MockMvcRequestBuilders.java:235) tại nl.bioprodict.blast.docs.PollControllerDocumentation.pollPending (PollControllerDocumentation java: 53) ...

các thử nghiệm Spring framework liên quan đến điều này mà tôi có thể tìm thấy tất cả sử dụng chế giễu có vẻ như: https://github.com/spring-projects/spring-framework/blob/master/spring-web/src/test/java/org/springframework/web/context/request/async/WebAsyncManagerTimeoutTests.java

Làm thế nào tôi có thể kiểm tra việc xử lý đúng đắn về DeferredResult timeoutResult?

+0

Để được rõ ràng: Có vẻ như để làm việc tốt trong các thử nghiệm hội nhập, nhưng tôi cũng muốn thử nghiệm này trong 'mùa xuân-restdocs-mockmvc'. – Tim

+0

Tôi vừa mới gặp phải vấn đề tương tự. Bạn đã bao giờ tìm thấy giải pháp cho phép kiểm tra thời gian chờ trên DeferredResults chưa? –

+0

@John nope, chưa, mặc dù tôi đã ngừng tìm kiếm ngay bây giờ .. Hãy cho tôi biết nếu bạn tìm thấy bất cứ điều gì! – Tim

Trả lời

3

Trong trường hợp của tôi, sau khi đi qua mã nguồn mùa xuân và thiết lập thời gian chờ (10000 mili giây) và nhận được kết quả async giải quyết nó cho tôi, như;

mvcResult.getRequest().getAsyncContext().setTimeout(10000); 
mvcResult.getAsyncResult(); 

Toàn bộ mã thử nghiệm của tôi là;

MvcResult mvcResult = this.mockMvc.perform(
           post("<SOME_RELATIVE_URL>") 
           .contentType(MediaType.APPLICATION_JSON) 
           .content(<JSON_DATA>)) 
         ***.andExpect(request().asyncStarted())*** 
          .andReturn(); 

***mvcResult.getRequest().getAsyncContext().setTimeout(10000);*** 
***mvcResult.getAsyncResult();*** 

this.mockMvc 
    .perform(asyncDispatch(mvcResult)) 
    .andDo(print()) 
    .andExpect(status().isOk()); 

Hy vọng nó giúp ..

+0

Cảm ơn! Upvoted như tôi cảm thấy nó có thể giúp đỡ một ai đó, nhưng trong trường hợp của tôi nó chưa làm việc hoặc với '@SpringBootTest()' cũng không '@WebMvcTest (PollController.class)'. Cả hai tiếp tục ném lên: 'Kết quả trì hoãn đã không được thiết lập trong timeToWait quy định = 25000' .. Cảm ơn mặc dù! – Tim

Các vấn đề liên quan