【问题标题】:MockMvcRequestBuilders.asyncDispatch providing an empty HTTP Response and contentTypeMockMvcRequestBuilders.asyncDispatch 提供空的 HTTP 响应和 contentType
【发布时间】:2019-06-22 01:12:04
【问题描述】:

我有一个单元测试,在使用 Spring 4.3 将方法转换为返回 StreamingResponseBody 之后,我试图检查正在发出的异步请求的响应。

测试方法如下:

final MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(wac)
     .apply(SecurityMockMvcConfigurers.springSecurity())
     .build();

MvcResult mvcResult1 = mockMvc.perform(
   get("/reports/generic/100?FIELD1=&FIELD3=").headers(STANDARD_HEADERS.get()))
  .andExpect(status().isOk())
  .andExpect(request().asyncStarted())
  .andReturn();

mvcResult1.getAsyncResult();

mockMvc.perform(asyncDispatch(mvcResult1))
                    .andExpect(status().isOk())
                    .andExpect(content().contentType("text/csv"))
                    .andExpect(content().string("Test Data" + System.lineSeparator() + "FIELD1=" + System.lineSeparator() + "FIELD3=" + System.lineSeparator()))

它调用的方法如下:

public StreamingResponseBody streamReport(@PathVariable("type") @NotNull String type, @PathVariable("id") @NotNull Long id, ReportConfiguration config, HttpServletResponse response) throws Exception {


    ReportServiceHandler handler = reportHandlerFactory.getHandler(type);
    final String reportFilename = handler.getReportFileName(id, reportConfiguration);

    response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + reportFilename);
    response.setContentType("text/csv");

    return new StreamingResponseBody() {

        @Override
        public void writeTo(OutputStream outputStream) throws IOException {

            try {
                response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + reportFilename);
                response.setContentType("text/csv");
                ServletOutputStream out = (ServletOutputStream) outputStream;
                handler.generateReport(out, id, reportConfiguration);
                out.flush();
            } catch ( Exception e ) {
                response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "inline");
                response.setContentType("");
                throw new IOException(e);
            }
        }
    };
}

调试显示原始请求中包含来自异步的响应,但异步响应对象(在 mvcResult1 内)没有 期间被复制asyncDispatch 所以 contextType 和 content 字符串都是空的。

这里是否遗漏了处理异步 mvcResult 以便可以断言内容的测试配置?

【问题讨论】:

    标签: java spring spring-mvc spring-test spring-test-mvc


    【解决方案1】:

    我在这方面做得相当成功。以下是我的不同做法:

        return new StreamingResponseBody() {
    
        @Override
        public void writeTo(OutputStream outputStream) throws IOException {
    
            try {
                ... same
                out.flush();
            } catch ( Exception e ) {
                ... your error handling
            } finally {
                // Try to close the stream
                try {
                    if (out != null) {
                        out.close();
                    }
                } catch (Throwable t) {
                    // not much we can do
                }
            }
        }
    };
    

    现在,我的测试与您的测试平行。阅读您的代码时,我不确定您为什么调用 perform() 两次。对我来说只需要一次。

    //Same
    final MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(wac)
       .apply(SecurityMockMvcConfigurers.springSecurity())
       .build();
    
    // Same
    MvcResult mvcResult1 = mockMvc.perform(
    get(....))
      .andExpect(status().isOk())
      .andExpect(request().asyncStarted())
      .andReturn();
        
    mvcResult1.getAsyncResult();
    
    // From this point on, I have complete response,
    // if it's not bugging you to place the entire file in memory
    String thisIsYourFileContent = mvcResult1.getResponse().getContentAsString();
    
    // Go on asserting the content of the file...
    

    希望这对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 2016-10-20
      • 1970-01-01
      • 1970-01-01
      • 2021-02-12
      • 2020-09-16
      • 2013-03-17
      • 2018-09-24
      • 1970-01-01
      • 2011-09-30
      相关资源
      最近更新 更多