views:

85

answers:

4

Hi

I have a little JUnit-Test that export an Object to the FileSystem. In the first place my test looked like this

public void exportTest {
   //...creating a list with some objects to export...    
   JAXBService service = new JAXBService();
   service.exportList(list, "output.xml");
}

Usually my test contain a assertion like assertEquals(...). So I changed the code to the following

public void exportCustomerListTest() throws Exception {
    // delete the old resulting file, so we can test for a new one at the end
    File file = new File("output.xml");
    file.delete();

    //...creating a list with some objects to export...

    JAXBService service = new JAXBService();
    service.exportCustomers(list, "output.xml");

    // Test if a file has been created and if it contains some bytes
    FileReader fis = new FileReader("output.xml");
    int firstByte = fis.read();

    assertTrue(firstByte != -1 );
}

Do I need this, or was the first approach enough? I am asking because, the first one is actually just "testing" that the code runs, but not testing any results. Or can I rely on the "contract" that if the export-method runs without an exception the test passes?

Thanks

+4  A: 

Well, you're testing that your code runs to completion without any exceptions - but you're not testing anything about the output.

Why not keep a file with the expected output, and compare that with the actual output? Note that this would probably be easier if you had an overload of expertCustomers which took a Writer - then you could pass in a StringWriter and only write to memory. You could test that in several ways, with just a single test of the overload which takes a filename, as that would just create a FileOutputStream wrapped in an OutputStreamWriter and then call the more thoroughly tested method. You'd really just need to check that the right file existed, probably.

Jon Skeet
A: 

you could use

assertTrue(new File("output.xml")).exist());

if you notice problems during the generation of the file, you can unit test the generation process (and not the fact that the file was correctly written and reloaded from the filesystem)

You can either go with the "gold file" approach (testing that two files are 1 to 1 identical) or test various outputs of your generator (I imagine that the generation of the content is separated from the saving into the file)

Vladimir
+1  A: 

I agree with the other posts. I will also add that your first test won't tell a test suite or test runner that this particular test has failed.

spdaly
A: 

Sometimes a test only needs to demonstrate that no exceptions were thrown. In that case relying that an exception will fail the test is good enough. There is certainly nothing gained in JUnit by calling the assertEquals method. A test passes when it doesn't throw an AssertionException, not because that method is called. Consider a method that allows null input, you might write a test like this:

 @Test public void testNullAllowed() {
      new CustomObject().methodThatAllowsNull(null);
 }

That might be enough of a test right there (leave to a separate test or perhaps there is nothing interesting to test about what it does with a null value), although it prudent to leave a comment that you didn't forget the assert, you left it out on purpose.

In your case, however, you haven't tested very much. Sure it didn't blow up, but an empty method wouldn't blow up either. Your second test is better, at least you demonstrate a non-empty file was created. But you can do better than that and check that at least some reasonable result was created.

Yishai