Issue
I have code where I check the exceptions in jUnit. I want to know which of the following is a good jUnit practice?
First
@Rule
public ExpectedException exception = ExpectedException.none();
@Test
public void checkNullObject() throws CustomException {
exception.expect(CustomException.class);
MyClass myClass= null;
MyCustomClass.get(null);
}
Second
@Test(expected=CustomException.class)
public void checkNullObject() throws CustomException {
MyClass myClass= null;
MyCustomClass.get(null);
}
EDIT: Please note that CustomException is a unchecked custom exception. (Though it won't have any impact on this question).
Solution
It depends what you want to check in the exception. If all you're doing is checking that the exception is thrown, then using @Test(expected=...)
is probably the easiest way:
@Test(expected=CustomException.class)
public void checkNullObject() throws CustomException {
MyClass myClass= null;
MyCustomClass.get(null);
}
However, the @Rule ExpectedException has a lot more options, including checking the message, from the javadoc:
// These tests all pass.
public static class HasExpectedException {
@Rule
public ExpectedException thrown= ExpectedException.none();
@Test
public void throwsNothing() {
// no exception expected, none thrown: passes.
}
@Test
public void throwsNullPointerException() {
thrown.expect(NullPointerException.class);
throw new NullPointerException();
}
@Test
public void throwsNullPointerExceptionWithMessage() {
thrown.expect(NullPointerException.class);
thrown.expectMessage("happened?");
thrown.expectMessage(startsWith("What"));
throw new NullPointerException("What happened?");
}
@Test
public void throwsIllegalArgumentExceptionWithMessageAndCause() {
NullPointerException expectedCause = new NullPointerException();
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("What");
thrown.expectCause(is(expectedCause));
throw new IllegalArgumentException("What happened?", cause);
}
}
So you can check for the message, the original cause of the exception. For checking the message, you can use matchers, so you can check startsWith()
and similar.
One reason to use the old style (Junit 3) throw/catch is if you have specific requirements. There aren't many of these, but it can happen:
@Test
public void testMe() {
try {
Integer.parseInt("foobar");
fail("expected Exception here");
} catch (Exception e) {
// OK
}
}
Answered By - Matthew Farwell