Unit Testing Exceptions

  • Write JUnit tests to check whether exceptions are thrown when expected.
  • Differentiate when to throw exceptions and when to try/catch the 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().