JUnit FAQ


Q: How do I test a method that returns a primitive?
A: Use assertEquals for int, char or float, use assertTrue or assertFalse for boolean.
    
E.g. assertEquals(3, word.length());
               3 is expected
               word.length() is actual

     assertEquals(3.0, circle.getCircumference(),0.1);
     assertTrue(game.isOver());


     DON'T DO THIS: assertTrue(3 == word.length())


Q: How do I test a method that returns an Object?
A: Use assertEquals

E.g. assertEquals("spades", card.getSuit());

Q: How do I test a private method?
A: Indirectly, by testing the method it supports.

   E.g., word has a private method vowelCounter() and a public method
         numberOfVowels()
   assertEquals(3, word.numberOfVowels());

Q: Why does my test fail when the message says "expected: Dave was: Dave". Aren't they equal?
A: You probably have a class with a toString() method that displays just the name. In this case you have two objects with the same name, but probably different values in other fields, like different ages.

Q: What's the best way to test that exceptions are being caught correctly?
A:
try
{
    some_statement;  // this is supposed to throw an exception
    fail();          // execution shouldn't get here, so fail if it does
}
catch(SomeException ex)
{
    ; // do nothing, we expect this to happen
}
// the test cases ends without failing, so its recorded as passing

Q: How do I test a void method (or constructor)?
A: Indirectly.  Check state of object via an accessor.

   E.g.  Queue has a void method remove() that removes the first object.
   myqueue.add(5);
   myqueue.add(3);
   myqueue.remove();
   assertEquals(3, myqueue.peek());


   (Assumes add() has already been verified).

Q: What if there isn't a public accessor method to the specific field I want to query?
A: Then perhaps you shouldn't be trying to access it. If you really must, create a package private accessor that only JUnit can see.

Q: Do I need to write tests for getters and setters?
A: If they contain no logic, then no. But that brings up a secondary issue, if your instance field has a getter and setter with no logic, then aren't you breaking encapsulation? (There's no difference between a private instance field with setter/getter and a public instance field.)

Q: What if two mutators are both broken, but in complimentary ways that disguises the defect in the method under test?  
A: This is pretty rare, but it does happen.  Be sure to do an assert after each mutation separately.

   For example, if add() and remove() are both broken,
        myqueue.add(5);
        myqueue.remove();
        assertEquals(0, myqueue.size());

   will pass.

   So better would be:
        myqueue.add(5);
        assertEquals(1, myqueue.size());
        assertEquals(5, myqueue.peek());
        myqueue.remove();
        assertEquals(0, myqueue.size());



Q: What if my method under test is broken, and my accessor is also broken in a way
that disguises the defect in the method under test?  
A: This is pretty rare, but it does happen.  You have to exercise the methods multiple
times in different combinations in order to isolate the behavior.

    If size() is broken and always returns 1, this test will pass.
        myqueue.add(5);
        assertEquals(1, myqueue.size());


   So use different combinations:
        assertEquals(0, myqueue.size());
        myqueue.add(5);
        assertEquals(1, myqueue.size());

Q: What about Observables?  How do I write a JUnit test for an Observable?
A: Have your JUnit test implement Observer, and in the update() method, place an assert for the appropriate condition.

Q: Does JUnit run my tests in the order they appear in the source code?
A: No. There is no guarantee the tests will be run in any particular order.

Q: Can I create an external data file within my JUnit test?
A: This is discouraged. It's better to construct your method so that it takes a Reader as a parameter, which is easier to create tests for. But if you insist:
    private void writeData(String testdata)
    {
        PrintWriter writer = null;
        try {
	    writer = new PrintWriter(new FileWriter("inputdata.txt"));
            writer.println(testdata);
            writer.close();
        } catch (Exception ex)
        {
            ex.printStackTrace();
        }  
    }

Q: How do I test that a FileNotFoundException is being caught correctly?
A: Have your method return true if it succeeds, and have the catch block return false. Then simply call your method with a file you know doesn't exist. See this example.

Q: How can I force my test to throw IOException?
A: The only methods that throw IOException are low level IO operations. There are no assignments in Mr. Dalbey's course that require low level IO. You should probably be using a Scanner instead.
If you insist, there is a way to do it, but you aren't going to like it because it uses mock objects. See example code.


Writing Fakes FAQ

Q: What should a fake do?
A:  The bare minimum needed so that the caller will execute.  E.g, return 1, return ' ', return true, etc.

Q: What if the caller expects different return values?  For example, a gameOver() boolean method, that the caller has logic that we want to test that does different things for true than false.
A: You could write two different fakes.  Or you could be clever and do something in the fake to modify the return value; perhaps the simplest would be to have the method alternate between returning true or false every time it is called.

Q: What about void methods?  Since they don't return anything, how do we know that the caller invoked them?
A: Use state verification.  The void method modifies an instance variable and an package private accessor makes it available to the unit test.




JUnit Style Guide
Dr. Dalbey's home page