【问题标题】:How to test a controller with streamed content with MockMvc?如何使用 MockMvc 测试具有流式内容的控制器?
【发布时间】:2016-03-28 20:53:57
【问题描述】:

我想用 MockMvc 测试一个没有 Spring 上下文的 Spring 控制器。 此控制器通过将内容写入响应的 OutputStream流式传输内容。

这是控制器代码:

@RequestMapping(method = GET, value = "/file")
public void getFile(HttpServletResponse response) throws IOException {
    response.setHeader("Content-Disposition", "attachment; filename=file.json");
    ObjectWriter objectWriter = new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL).writer();

    Item item = new Item();
    List<Item> items = new ArrayList<>();
    items.add(item);

    try (Writer bufferedWriter = new BufferedWriter(new OutputStreamWriter(response.getOutputStream()))) {
        objectWriter.writeValue(bufferedWriter, items);
        bufferedWriter.flush();
    }
}

这是测试:

@Test
public void getFile_ok() throws Exception {
    mockMvc.perform(get(END_POINT + "/file").accept(MediaType.APPLICATION_JSON))
           .andExpect(status().isOk());
}

此控制器运行良好,但单元测试失败并出现 IOException:

java.io.IOException: Stream closed
    at java.io.BufferedWriter.ensureOpen(BufferedWriter.java:116)
    at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:126)
    at java.io.BufferedWriter.flush(BufferedWriter.java:253)

【问题讨论】:

    标签: java spring spring-mvc outputstream mockmvc


    【解决方案1】:

    实际上objectWriter.writeValue(bufferedWriter, items); 试图关闭流。

    Javadoc:

    注意:方法在这里没有显式关闭底层流; 但是,这个映射器使用的 JsonFactory 可以选择关闭流 取决于它的设置(默认情况下,它会尝试关闭它 我们构造的 JsonGenerator 是关闭的)。

    在运行时,它不会关闭它,但在我的测试中,它会关闭它,并且下一行 bufferedWriter.flush(); 只是发送 IOEception

    所以为了修复它,我以这种方式添加了一个 try/catch:

    try {
        writer.flush();
    } catch (IOException e) {
        logger.info("Stream closed in writeValue()", e);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-11
      • 1970-01-01
      • 2014-05-31
      • 1970-01-01
      • 2021-03-14
      • 2021-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多