Skip to content

How can I transform an uncompressed file into zipped bytes?

In Java for a JUnit test, I am trying to mock a function that downloads a Zip File from another external API’s endpoint. To simulate the download, I need to zip a test file and transform it into bytes to use as the mock’s return value. I do not need to write the zipped file back to the file system but use the bytes raw as they are.

mock(zipReturner.getZipBytes()).thenReturn(testFileAsZippedBytes("testFile.txt"))
private Optional<byte[]> testFileAsZippedBytes(String testFile) {
  ???
}

Answer

Sharing my answer, because all the other examples I found are much heavier, require many more lines of code looping over bytes, or require using external libraries to do the same thing.

To do this without the above, use a combination of ByteArrayOutputStream, as it has the toByteArray function, ZipOutputStream to write zipped bytes to the ByteArrayOutputStream and FileInputStream to read the test file from the file system.

private Optional<byte[]> testFileAsZippedBytes(String filePath, String fileName) throws IOException {
  try (
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream);
    FileInputStream fileInputStream = new FileInputStream(filePath + fileName);
  ) {
    ZipEntry zipEntry = new ZipEntry(fileName);
    zipOutputStream.putNextEntry(zipEntry);
    zipOutputStream.write(fileInputStream.readAllBytes());
    zipOutputStream.finish();
    return Optional.of(byteArrayOutputStream.toByteArray());
  }
}

Use ZipEntry to add the file as an entry to the ZipOutputStream and write the bytes to the zip. Use zipOutputStream.finish() to ensure all contents are written to the stream and are ready to be consumed in the ByteArrayOutputStream, otherwise it was my experience that you would only get partial data when you call byteArrayOutputStream.toByteArray().