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) { ??? }
Advertisement
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()
.