Search code examples
javaspringunit-testingjunitjunit4

Testcase for creating zip file in java junit


I'm written an method which is accepting a file and then after it's creating a zip file. once zip file creation is done, then it's trying to store that in GCS bucket and deleting those file from temp dir. Could anyone help me one this to write the test cases for this.

private void createZip(File file) throws IOException {
    File zipFile = new File(System.getProperty("java.io.tmpdir"), Constants.ZIP_FILE_NAME);

    if (!file.exists()) {
        logger.info("File Not Found For To Do Zip File! Please Provide A File..");
        throw new FileNotFoundException("File Not Found For To Do Zip File! Please Provide A File..");
    }

    try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));
        FileInputStream fis = new FileInputStream(file);) {

        ZipEntry zipEntry = new ZipEntry(file.getName());
        zos.putNextEntry(zipEntry);

        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) > 0) {
            zos.write(buffer, 0, len);
        }
        zos.closeEntry();
    }

    try {
        // store to GCS bucket
        GcpCloudStorageUtil.uploadFileToGcsBucket(zipFile, zipFile.getName());
        file.delete();
        zipFile.delete();
    } catch (Exception e) {
        logger.error("Exception" + e);
        throw new FxRuntimeException("Exception " + e.getMessage());
    }

}

Solution

  • As a general rule of thumb when designing test cases you want to consider both the expected behaviour if everything goes right and the expected behaviours for each way that things could go wrong.

    For your particular problem, when everything goes right you should expect your method to compress the file given as argument, upload it and delete the file from the temp directory. You can do so by spying on your static GcpCloudStorageUtil method. Spies are instances of a class which retain their usual behaviour unless specified and which method calls you can monitor. You can read more on the topic here and here (for static method spying).

    It's hard to give a thorough answer without access to the rest of your code but I'd suggest :

    • creating a non empty file
    • calling the createZip method on this file
    • verifying that the GcpCloudStorageUtil.uploadFileToGcsBucket method was called
    • verifying that the uploaded file content matches the file you created
    • verifying that the temp directory is now empty

    There are also a number of way that things could go wrong. For instance the file given as argument might not exist. You want to write a test case which ensures that a FileNotFoundException is thrown in this case. This article covers different ways to do this using JUnit4 or JUnit5.

    Similarly you could design a test case where you mock the GcpCloudStorageUtil.uploadFileToGcsBucket and force it to throw an exception then verify that the expected exception was thrown. Mocking a method means forcing it to behave a certain way (here, throw an exception). Again you can read more on the topic here.

    Edit : Here is a possible test class.

    @SpringBootTest
    public class ZipperTest {
        MockedStatic<GcpCloudStorageUtil> mockGcpCloudStorageUtil;
    
        @Before
        public void init(){
            mockGcpCloudStorageUtil = Mockito.mockStatic(GcpCloudStorageUtil.class);
        }
    
        @After
        public void clean(){
            mockGcpCloudStorageUtil.close();
        }
    
    
        @Test
        public void testFileIsUploadedAndDeleted() throws IOException, FxRuntimeException {
            //mocks the GcpCloudStorageUtil class and ensures it behaves like it normally would
            mockGcpCloudStorageUtil.when(() -> GcpCloudStorageUtil.uploadFileToGcsBucket(Mockito.any(File.class), Mockito.anyString())).thenCallRealMethod();
    
            Zipper zipper = new Zipper();
    
            //creates a file
            String content = "My file content";
            Files.write(Paths.get("example.txt"),
                    List.of(content),
                    StandardCharsets.UTF_8,
                    StandardOpenOption.CREATE,
                    StandardOpenOption.APPEND);
    
            zipper.createZip(new File("example.txt"));
    
            //verifies that the uploadFileToGcsBucket method was called once
            mockGcpCloudStorageUtil.verify(()->GcpCloudStorageUtil.uploadFileToGcsBucket(Mockito.any(File.class), Mockito.anyString()), times(1));
    
            //you can insert code here to verify the content of the uploaded file matches the provided file content
    
            //verifies that the file in the temp directory has been deleted
            Assert.assertFalse(Files.exists(Paths.get(System.getProperty("java.io.tmpdir")+"example.txt")));
    
        }
    
        @Test(expected = FileNotFoundException.class)
        public void testExceptionThrownWhenFileDoesNotExist() throws FxRuntimeException, IOException {
            mockGcpCloudStorageUtil.when(() -> GcpCloudStorageUtil.uploadFileToGcsBucket(Mockito.any(File.class), Mockito.anyString())).thenCallRealMethod();
    
            Zipper zipper = new Zipper();
            zipper.createZip(new File("doesnt_exist.txt"));
            //verifies that the uploadFileToGcsBucket method was not called
            mockGcpCloudStorageUtil.verifyNoInteractions();
    
        }
    
        @Test(expected = FxRuntimeException.class)
        public void testExceptionThrownWhenIssueGcpUpload() throws IOException, FxRuntimeException {
            //this time we force the uploadFileToGcsBucket method to throw an exception
            mockGcpCloudStorageUtil.when(() -> GcpCloudStorageUtil.uploadFileToGcsBucket(Mockito.any(File.class), Mockito.anyString())).thenThrow(RuntimeException.class);
    
            Zipper zipper = new Zipper();
    
            //creates a file
            String content = "My file content";
            Files.write(Paths.get("example.txt"),
                    List.of(content),
                    StandardCharsets.UTF_8,
                    StandardOpenOption.CREATE,
                    StandardOpenOption.APPEND);
    
            zipper.createZip(new File("example.txt"));
            mockGcpCloudStorageUtil.verify(()->GcpCloudStorageUtil.uploadFileToGcsBucket(Mockito.any(File.class), Mockito.anyString()), times(1));
    
        }
    }