Unit Testing Exceptions
Let's update IndexedListTest
to include tests to check that the IndexOutOfBoundsException
is thrown when expected.
@Test
@DisplayName("get() throws exception if index is below the valid range.")
void testGetWithIndexBelowRangeThrowsException() {
try {
numbers.get(-1);
fail("IndexOutOfBoundsException was not thrown for index < 0");
} catch (IndexOutOfBoundsException ex) {
return;
}
}
@Test
@DisplayName("get() throws exception if index is above the valid range.")
void testGetWithIndexAboveRangeThrowsException() {
try {
numbers.get(size + 1);
fail("IndexOutOfBoundsException was not thrown for index > length");
} catch (IndexOutOfBoundsException ex) {
return;
}
}
Notice the approach to test that an exception is thrown when it is expected to be thrown:
try {
// call a method with an invalid input
obj.someMethodThatThrowsException(badInput);
// we expect the execution stops
// and goes to the catch block as a result of an exception
// if we get passed this point, exception was not thrown
// we must deliberately signal the test has failed!
fail("The expected exception was not thrown!");
} catch (ExpectedException ex) {
// if we are here, the expected exception is thrown;
// there is nothing to do, we can "return"
// to indicate the test has successfully passed
return;
}
The fail
method is part of JUnit's Assertions
library
import static org.junit.jupiter.api.Assertions.fail;
Run the tests and see them fail!
Resources
If you need a refresher on Java's Exception, please visit Exceptions on Oracle's [online] Java Tutorial. Alternatively, you can read this article on Java Exceptions.
JUnit 5 includes assertThrows()
method that provides a more elegant approach to check an exception is thrown. We will not use this alternative approach because it involves the use of Java's Lambda expression:
assertThrows(IndexOutOfBoundsException.class, () -> {
numbers.get(-1);
});
This post provides a more detailed example on using assertThrows()
.