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