【问题标题】:How to assert response in zipoutputstream如何在 zipoutputstream 中断言响应
【发布时间】:2017-07-31 15:38:33
【问题描述】:

我正在尝试使用 MockitoJUnitRunner 编写 JUnit。 我正在将文件 ID 传递给我的函数,该函数正在从云下载文件并将 zip 文件作为下载返回。 这是我的代码

public void getLogFile(HttpServletResponse response, String id) throws IOException {

    response.setContentType("Content-type: application/zip");
    response.setHeader("Content-Disposition", "attachment; filename=LogFiles.zip");

    ServletOutputStream out = response.getOutputStream();
    ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(out));

    zos.putNextEntry(new ZipEntry(id));

    InputStream inputStream = someDao.getFile(id);

    BufferedInputStream fif = new BufferedInputStream(inputStream);

    int data = 0;

    while ((data = fif.read()) != -1) {
        zos.write(data);
    }

    fif.close();

    zos.closeEntry();
    zos.close();
}

而我的 JUnit 函数是

@Mock
private MockHttpServletResponse mockHttpServletResponse;

anyInputStream = new ByteArrayInputStream("test data".getBytes());

    @Test
    public void shouldDownloadFile() throws IOException {

    ServletOutputStream outputStream = mock(ServletOutputStream.class);

        when(mockHttpServletResponse.getOutputStream()).thenReturn(outputStream);


 =>          when(someDao.download(anyString())).thenReturn(anyInputStream);


        controller.getLogFile(mockHttpServletResponse, id);

        verify(mockHttpServletResponse).setContentType("Content-type: application/zip");

        verify(mockHttpServletResponse).setHeader("Content-Disposition","attachment; filename=LogFiles.zip");

        verify(atmosdao).download(atmosFilePath);
    }

这个单元测试通过了,但是我想验证 outputStream 上写了什么,我该怎么做?当我将“测试数据”写入模拟的 outputStream 时,就像

anyInputStream = new ByteArrayInputStream("test data".getBytes());

when(someDao.download(anyString())).thenReturn(anyInputStream);

mockHttpServletResponse.getContentAsString() 给我 null !

是否可以断言使用 zipoutputStream 编写的MockHttpServletResponse?如果是,那我该怎么做?

谢谢。

【问题讨论】:

    标签: java unit-testing junit mockito spring-test-mvc


    【解决方案1】:

    我得到了我想要的东西... 这就是我使用 powerMockito 断言写入 zipoutputStream 的数据所做的。

    @Test
    public void ShouldAttemptToWriteDownloadedFileToZipOutputStream() throws Exception {
    
        InputStream anyInputStream = new ByteArrayInputStream("test data".getBytes());
    
        ServletOutputStream outputStream = mock(ServletOutputStream.class);
    
        BufferedOutputStream bufferedOutputStream = Mockito.mock(BufferedOutputStream.class);
        PowerMockito.whenNew(BufferedOutputStream.class).withArguments(outputStream).thenReturn(bufferedOutputStream);
    
        ZipOutputStream zipOutputStream = Mockito.mock(ZipOutputStream.class);
        PowerMockito.whenNew(ZipOutputStream.class).withArguments(bufferedOutputStream).thenReturn(zipOutputStream);
    
        BufferedInputStream bufferedInputStream = new BufferedInputStream(anyInputStream);
        PowerMockito.whenNew(BufferedInputStream.class).withArguments(anyInputStream).thenReturn(bufferedInputStream);
    
        subjectUnderTest.getLogFile(mockHttpServletResponse, "12345");
    
        int data = 0;
    
        while ((data = bufferedInputStream.read()) != -1) {
    
            verify(zipOutputStream).write(data);
        }
    }
    

    感谢雨果的帮助!

    【讨论】:

      【解决方案2】:

      您可以创建一个自定义的,而不是模拟您的 OutputStream

      public class CustomOutputStream extends ServletOutputStream {
          private ByteArrayOutputStream out = new ByteArrayOutputStream();
          private String content;
      
          @Override
          public void write(int b) throws IOException {
              out.write(b);
          }
      
          @Override
          public void close() throws IOException {
              content = new String(out.toByteArray());
              out.close();
              super.close();
          }
      
          public String getContentAsString() {
              return this.content; 
          }
      }
      

      这个类将存储所有写入它的字节并将它们保存在content字段中。

      然后你替换这个:

      ServletOutputStream outputStream = mock(ServletOutputStream.class);
      

      通过这个:

      CustomOutputStream outputStream = new CustomOutputStream();
      

      当您的 servlet 调用 getOutputStream() 时,它将使用自定义的,最后 getContentAsString() 将返回您写入 servlet 的输出。

      注意:输出是压缩的,所以字符串会包含奇怪的字符。如果您想要原始字符串,则必须将其解压缩(在这种情况下,我将使用 out.toByteArray() 返回的字节数组而不是字符串,因为当您以这种方式创建字符串时,您可能会遇到编码问题打电话给string.getBytes())

      【讨论】:

      • 嗨 Hugo,有没有办法检查输出流中是否存在 zip 文件?
      • 输出流写入到一个压缩文件(实际上,它正在生成“压缩”字节),所以压缩文件只有在某些客户端调用servlet并保存这些文件后才会存在字节到文件。这是你问的还是我理解错了?
      • 其实我想在junit中断言servletoutputstream是否有zip文件(zipoutputstream)?
      • 我认为你不需要断言它。当您执行when(mockHttpServletResponse.getOutputStream()).thenReturn(outputStream) 时,您是在说您的servlet 已经有一个输出流(因为它会被返回,因为它已经被模拟了)。相反,我会断言结果(getContentAsString,或者更好的是,用于构建它的字节 - 在out.toByteArray() 中返回的字节)。由于您的输入始终相同(“测试数据”),因此很容易检查压缩字节。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多