Testing Spring asyncResult() and jsonPath() together

后端 未结 3 1353
走了就别回头了
走了就别回头了 2021-02-13 09:08

I\'m using a restful url to kick off a long-running backend process (it is normally on a cron schedule, but we want the ability to kick it off manually).

The code below

3条回答
  •  陌清茗
    陌清茗 (楼主)
    2021-02-13 09:54

    Matt's answer is correct, but I would like perform to just work. Below is a perform method that you can use to test both async and sync requests. So you don't need to care in your tests how backend handles the requests. You are only interested of the actual response anyway, right?

    ResultActions perform(MockHttpServletRequestBuilder builder) throws Exception {
        ResultActions resultActions = mockMvc.perform(builder);
        if (resultActions.andReturn().getRequest().isAsyncStarted()) {
          return mockMvc.perform(asyncDispatch(resultActions
              .andExpect(request().asyncResult(anything()))
              .andReturn()));
        } else {
          return resultActions;
        }
    }
    

    One way to integrate that to your tests is to put it in a common abstract base class and extend your actual test classes from it:

    import static org.hamcrest.Matchers.anything;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
    import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
    
    @WebAppConfiguration
    @ContextConfiguration("file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml")
    public abstract class AbstractMockMvcTests {
    
      @Autowired
      protected WebApplicationContext wac;
    
      private MockMvc mockMvc;
    
      @Before
      public void setup() throws Exception {
        mockMvc = webAppContextSetup(this.wac).build();
      }
    
      protected ResultActions perform(MockHttpServletRequestBuilder builder) throws Exception {
        ResultActions resultActions = mockMvc.perform(builder);
        if (resultActions.andReturn().getRequest().isAsyncStarted()) {
          return mockMvc.perform(asyncDispatch(resultActions
              .andExpect(request().asyncResult(anything()))
              .andReturn()));
        } else {
          return resultActions;
        }
      }
    }
    

    Then implement your tests by extending the base class and use the perform method. In this example mockMvc is made private to gently guide all future test authors to use the custom perform method.

    @RunWith(SpringJUnit4ClassRunner.class)
    public class CallableControllerTests extends AbstractMockMvcTests {
    
      @Test
      public void responseBodyAsync() throws Exception {
        perform(get("/async/callable/response-body"))
          .andExpect(status().isOk())
          .andExpect(content().contentType("text/plain;charset=ISO-8859-1"))
          .andExpect(content().string("Callable result"));
      }
    
      @Test
      public void responseBodySync() throws Exception {
        perform(get("/sync/foobar/response-body"))
          .andExpect(status().isOk())
          .andExpect(content().contentType("text/plain;charset=ISO-8859-1"))
          .andExpect(content().string("Sync result"));
      }
    }
    

提交回复
热议问题