The JUnit TestRunners will catch the thrown Exception regardless so you don't have to worry about your entire test suite bailing out if an Exception is thrown. This is the best answer.
In order to test the exception thrown by any method in JUnit 4, you need to use @Test(expected=IllegalArgumentException. class) annotation. You can replace IllegalArgumentException. class with any other exception e.g. NullPointerException.
Yes it is completely fine, and if it does throw the exception the test will be considered as failed. You need to specify that the method throws an Exception even if you know that the specific case does not (this check is done by the compiler).
Actually, the old style of exception testing is to wrap a try block around the code that throws the exception and then add a fail()
statement at the end of the try block. Something like this:
public void testNullParameter() {
try {
IPAddress addr = new IPAddress(null);
fail("InvalidIPAddressException not thrown.");
} catch(InvalidIPAddressException e) {
assertNotNull(e.getMessage());
}
}
This isn't much different from what you wrote but:
assertTrue(addr.getOctets() == null);
is useless.Still, this is a bit ugly. But this is where JUnit 4 comes to the rescue as exception testing is one of the biggest improvements in JUnit 4. With JUnit 4, you can now write your test like this:
@Test (expected=InvalidIPAddressException.class)
public void testNullParameter() throws InvalidIPAddressException {
IPAddress addr = new IPAddress(null);
}
Nice, isn't it?
Now, regarding the real question, if I don't expect an exception to be thrown, I'd definitely go for way #1 (because it's less verbose) and let JUnit handle the exception and fail the test as expected.
For tests where I don't expect an exception, I don't bother to catch it. I let JUnit catch the exception (it does this reliably) and don't cater for it at all beyond declaring the throws
cause (if required).
I note re. your first example that you're not making use of the @expected
annotation viz.
@Test (expected=IndexOutOfBoundsException.class) public void elementAt() {
int[] intArray = new int[10];
int i = intArray[20]; // Should throw IndexOutOfBoundsException
}
I use this for all tests that I'm testing for throwing exceptions. It's briefer than the equivalent catch/fail pattern that I had to use with Junit3.
Since JUnit 4.7 you have the possibility to use an ExpectedException rule and you should use it. The rule gives you the possibility to define exactly the called method where the exception should be thrown in your test code. Moreover, you can easily match a string against the error message of the exception. In your case the code looks like this:
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void test() {
//working code here...
expectedException.expect(InvalidIPAddressException.class);
IPAddress addr = new IPAddress(null);
}
UPDATE: In his book Practical Unit Testing with JUnit and Mockito Tomek Kaczanowski argues against the use of ExpectedException, because the rule "breaks the arrange/act/assert [...] flow" of a Unit test (he suggests to use Catch Exception Library instead). Although I can understand his argument, I think using the rule is fine if you do not want to introduce another 3rd-party library (using the rule is better than catching the exception "manually" anyway).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With