0

I have implemented a method to zip files. This method is capable of zipping subfolder, overwriting existing zip files and some more. Now I want to create unit tests for this method. I started with a default zip-file with some content so I could test the overwriting etc.

My method to set up the source files:

@Before
public void setUp() throws IOException, URISyntaxException {

    util = new ZipFileUtil();

    parent = folder.newFolder("Parent");
    File subfolder = folder.newFolder("Parent", "Subfolder");
    File sub2 = folder.newFolder("Parent", "Subfolder", "Sub2");

    File f1 = File.createTempFile("file1", ".txt", parent);
    File f2 = File.createTempFile("file2", ".txt", parent);
    File f3 = File.createTempFile("file3", ".txt", parent);

    File f4 = File.createTempFile("file4", ".txt", subfolder);
    File f5 = File.createTempFile("file5", ".txt", subfolder);

    File f6 = File.createTempFile("file6", ".txt", sub2);
    File f7 = File.createTempFile("file7", ".txt", sub2);

    File f8 = File.createTempFile("test", ".txt", sub2);

    File f9 = File.createTempFile("test1", ".txt", parent);

    files[0] = f1;
    files[1] = f2;
    files[2] = f3;
    files[3] = f4;
    files[4] = f5;
    files[5] = f6;
    files[6] = f7;
    files[7] = f8;
    files[8] = f9;

    File file = new File(getClass().getClassLoader().getResource("test.zip").toURI());

    Files.copy(file.toPath(), Paths.get(folder.getRoot().toString(), "test.zip"),
            StandardCopyOption.REPLACE_EXISTING);
}

And my test:

@Test
public void testOverwriteFilesInExistingZip() throws IOException {
    util.setZipNameGenerator(new ZipNamingStrategy() {

        @Override
        public String getName() {
            // TODO Auto-generated method stub
            return "test";
        }

    });
    util.setOverwriteFilesInExistingZip(true);
    util.setSourceFolder(parent);
    util.setDestinationFolder(folder.getRoot());
    util.generateZip(new FilenameFilter() {

        @Override
        public boolean accept(File dir, String name) {
            return true;

        }
    });
    FileSystem fs = FileSystems.newFileSystem(Paths.get(folder.getRoot().getAbsolutePath(), "test.zip"), null);

    assertEquals("/" + files[0].getName(),
            fs.getPath("/", parent.toPath().relativize(files[0].toPath()).toString()).toString());
    assertEquals("/" + files[1].getName(),
            fs.getPath("/", parent.toPath().relativize(files[1].toPath()).toString()).toString());
    assertEquals("/" + files[2].getName(),
            fs.getPath("/", parent.toPath().relativize(files[2].toPath()).toString()).toString());
    assertEquals(true,
            new File(fs.getPath("/", parent.toPath().relativize(files[8].toPath()).toString()).toString()).exists());

    assertEquals("/file.txt", fs.getPath("/", "file.txt").toString());
    assertEquals("/New Text Document.txt", fs.getPath("/", "New Text Document.txt").toString());
    assertEquals("/test.txt", fs.getPath("/", "test.txt").toString());
    assertEquals("/test1.txt", fs.getPath("/", "test1.txt").toString());

    assertEquals("/Subfolder/file.txt", fs.getPath("/", "test1.txt").toString());
    assertEquals("/Subfolder/desktop.ini", fs.getPath("/", "test1.txt").toString());
    assertEquals("/Subfolder/test.txt", fs.getPath("/", "test1.txt").toString());
    assertEquals("/Subfolder/New Text Document.txt", fs.getPath("/", "test1.txt").toString());

    assertEquals(15, util.getProcessedFiles());

}

I am kinda lost on how to properly check if the zip file has the right structure (files have to exist in the file). Currently I am just checking the paths, but this is so wrong and I know it. Can anyone enlighten me on how to properly test this kind of method?

XtremeBaumer
  • 6,275
  • 3
  • 19
  • 65
  • This is a little unclear. Can you just unzip it and check the contents? – Oliver Charlesworth Dec 05 '17 at 14:39
  • @OliverCharlesworth surely i could, but this would mess up the paths probably and i want to check if its all right **inside** the zip file – XtremeBaumer Dec 05 '17 at 14:43
  • Is it correct that `ZipFileUtil` is not a Class that you have written? – Herr Derb Dec 05 '17 at 14:43
  • @HerrDerb it's my own class and from what i tested by hand its working as it should – XtremeBaumer Dec 05 '17 at 14:44
  • What do you mean by "mess up the paths"? Why can't you just unzip into a temporary directory, and compute relative filenames at that point? That said, it is possible to get Java to directly read content from a zip file (see e.g. https://stackoverflow.com/questions/15667125/read-content-from-files-which-are-inside-zip-file), it's just a bit of a pain. (If that link answers your question, then great! If not, could you clarify what exactly the remaining issue is?) – Oliver Charlesworth Dec 05 '17 at 14:45
  • In my opinion you are using way too much files for your test, which makes it very hard to read. As I see two directories where one contains 1 file and the other 2 files would be sufficient, to test the functionality. – Herr Derb Dec 05 '17 at 14:46
  • @OliverCharlesworth i mean that the paths change then meaning they are no longer in the zip file. also i don't need to check the content, i need to check if the files were being processed at all to make sure it didn't miss any file – XtremeBaumer Dec 05 '17 at 14:47
  • @HerrDerb so like this: parent (1 file), subfolder (1 file) and sub2 (1 file)? – XtremeBaumer Dec 05 '17 at 14:48
  • Ok. But your code seems to be doing that already, other than the actual existence check (which you can do with `Files.exists(path)`). – Oliver Charlesworth Dec 05 '17 at 14:50
  • If you have a directory with 2 files, you don't need to test another directory with 3 files. You don't test anything more with this, it only produces more lines within your test, which should be avoided. If you do rootPath/file1, rootpath/sub/file2, /rootpath/sub/file3 you've already got everything covered, don't you? (multiple files and subfolder) – Herr Derb Dec 05 '17 at 14:52
  • @OliverCharlesworth `assertEquals("/" + files[2].getName(), fs.getPath("/", parent.toPath().relativize(files[2].toPath()).toString()).toString());` will be true as long as the relative paths match (in my opinion not enough). you are right that i can just test it with `Files.exists(path)`, thanks for this. @HerrDerb I think so – XtremeBaumer Dec 05 '17 at 14:55
  • This means the half of your `assert` checks actually do not provide anything to quality of the test. I recommend to shorten it down to the necessary then. This way you can take better care for the real testing goal. – Herr Derb Dec 05 '17 at 15:03
  • @HerrDerb i do know that my `assert` checks right now are far from good and i am looking to improve them. currently i am stuck on getting the full file paths for every file inside the zip – XtremeBaumer Dec 05 '17 at 15:07

1 Answers1

2

If you want to check whether these files exist within the zip file, you can use Files.exist(path).

If you want to go further and check the actual content, you can either unzip into a different temporary directory, or ask Java to read directly from the zip file.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • if you can give me a way through which i can get every file path inside the zip (file should actually exist too), i will accept your answer – XtremeBaumer Dec 05 '17 at 15:08
  • @XtremeBaumer - You could use a [`FileVisitor`](https://docs.oracle.com/javase/tutorial/essential/io/walk.html) (happy to add this to my answer :), but I'm not sure why that would be helpful - you already know what files should be there, so you could check for their existence directly. – Oliver Charlesworth Dec 05 '17 at 15:12
  • I already thought about walking the filetree, but i can't pack all the `asserts` inside 1 method which is called multiple times (some will always fail then). my "best" shot right now is to somehow get the path of my `FileSystem` (just to be sure i access the same files), but at the moment i can't find any way to do so (except using the parameter i used to create the `FileSystem` in the first place) – XtremeBaumer Dec 05 '17 at 15:31