Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-13615

MockMvc: afterCompletion is never called on CallableProcessingInterceptor and DeferredResultProcessingInterceptor

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Minor
    • Resolution: Complete
    • Affects Version/s: 4.2.2
    • Fix Version/s: 4.2.3
    • Component/s: Test
    • Labels:
      None

      Description

      If I run the application, it's called correctly but, in MockMvc tests, it's never called.

        Activity

        Hide
        rstoya05-aop Rossen Stoyanchev added a comment -

        Please provide an example of how the test is written.

        Show
        rstoya05-aop Rossen Stoyanchev added a comment - Please provide an example of how the test is written.
        Hide
        kewne João Cabrita added a comment -

        I've added a link to the pull request for my reproduction example.

        Show
        kewne João Cabrita added a comment - I've added a link to the pull request for my reproduction example.
        Hide
        rstoya05-aop Rossen Stoyanchev added a comment -

        Thanks for the detailed example.

        The interceptors are called as a result of the async request being completed and the servlet container notifying any registered AsyncListener's. We are registered, however in this case there is no Servlet container and hence no notifications. I think can do it in MockMvc after performing the async dispatch if the request has an AsyncContext and asyncStarted=false.

        In the mean time as a workaround you can call AsyncContext.complete() manually:

        @Test
        public void repro2() throws Exception {
            MvcResult r = mockMvc.perform(get("/dummyDeferred"))
                .andExpect(request().asyncStarted())
                .andReturn();
            mockMvc.perform(asyncDispatch(r)).andExpect(status().isOk());
            r.getRequest().getAsyncContext().complete();
            assertTrue(deferredResultInterceptor.executed.get());
        }
        

        Show
        rstoya05-aop Rossen Stoyanchev added a comment - Thanks for the detailed example. The interceptors are called as a result of the async request being completed and the servlet container notifying any registered AsyncListener's. We are registered, however in this case there is no Servlet container and hence no notifications. I think can do it in MockMvc after performing the async dispatch if the request has an AsyncContext and asyncStarted=false. In the mean time as a workaround you can call AsyncContext.complete() manually: @Test public void repro2() throws Exception { MvcResult r = mockMvc.perform(get( "/dummyDeferred" )) .andExpect(request().asyncStarted()) .andReturn(); mockMvc.perform(asyncDispatch(r)).andExpect(status().isOk()); r.getRequest().getAsyncContext().complete(); assertTrue(deferredResultInterceptor.executed.get()); }
        Hide
        kewne João Cabrita added a comment -

        How rude of me, thank you for the workaround, it works.

        I see that you also committed a "fix", thank you for taking the time to work on this and getting it done so quickly.

        Show
        kewne João Cabrita added a comment - How rude of me, thank you for the workaround, it works. I see that you also committed a "fix", thank you for taking the time to work on this and getting it done so quickly.

          People

          • Assignee:
            rstoya05-aop Rossen Stoyanchev
            Reporter:
            kewne João Cabrita
            Last updater:
            Stéphane Nicoll
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Days since last comment:
              2 years, 15 weeks, 5 days ago