简体   繁体   English

如何使用MockMvc测试具有流式内容的控制器?

[英]How to test a controller with streamed content with MockMvc?

I'd like to test a Spring controller, without Spring context, with MockMvc . 我想使用MockMvc测试没有Spring上下文的Spring控制器。 This controller streams the content by writing it in the OutputStream of the response. 该控制器通过将内容写入响应的OutputStream中传输内容。

Here is the controller code: 这是控制器代码:

@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();
    }
}

Here is the test: 这是测试:

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

This controller works well, but the unit test fails with an IOException: 该控制器运行良好,但是单元测试失败并出现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)

Actually the objectWriter.writeValue(bufferedWriter, items); 实际上是objectWriter.writeValue(bufferedWriter, items); tries to close the stream. 尝试关闭流。

Javadoc: 的Javadoc:

Note: method does not close the underlying stream explicitly here; 注意:方法不会在此处显式关闭基础流; however, JsonFactory this mapper uses may choose to close the stream depending on its settings (by default, it will try to close it when JsonGenerator we construct is closed). 但是,此映射器使用的JsonFactory可能会根据其设置选择关闭流(默认情况下,当我们构造的JsonGenerator关闭时,它将尝试关闭流)。

In runtime, it doesn't close it but in my tests, it does, and the next line bufferedWriter.flush(); 在运行时,它不会关闭它,但是在我的测试中会关闭它,并且下一行bufferedWriter.flush(); just sends the IOEception . 只是发送IOEception

So to fix it I added a try/catch this way: 因此,要解决此问题,我以这种方式添加了try / catch:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM