How do you assert that an exception was thrown in JUnit 4 tests?

Keywords: Junit less Attribute

How to use JUnit 4 to test some code to throw exceptions?

Although I can certainly do such things:

@Test
public void testFooThrowsIndexOutOfBoundsException() {
  boolean thrown = false;

  try {
    foo.doStuff();
  } catch (IndexOutOfBoundsException e) {
    thrown = true;
  }

  assertTrue(thrown);
}

I remember in this case, having an annotation or an asset.xyz or something less cluttered is the essence of JUnit.

#1 building

I've tried a lot of methods here, but they're either complicated or they don't exactly meet my requirements. In fact, you can simply write a helper method:

public class ExceptionAssertions {
    public static void assertException(BlastContainer blastContainer ) {
        boolean caughtException = false;
        try {
            blastContainer.test();
        } catch( Exception e ) {
            caughtException = true;
        }
        if( !caughtException ) {
            throw new AssertionFailedError("exception expected to be thrown, but was not");
        }
    }
    public static interface BlastContainer {
        public void test() throws Exception;
    }
}

Use it like this:

assertException(new BlastContainer() {
    @Override
    public void test() throws Exception {
        doSomethingThatShouldExceptHere();
    }
});

Zero dependency: no simulation, no powermock; and works well on the final course.

#2 building

What to do: catch a very common exception, make sure it leaves the catch block, and then assert that the exception's class is the exception you expect. If a) the exception is of the wrong type (for example, if you use a Null pointer instead), and b) never throws an exception, the assertion fails.

public void testFooThrowsIndexOutOfBoundsException() {
  Throwable e = null;

  try {
    foo.doStuff();
  } catch (Throwable ex) {
    e = ex;
  }

  assertTrue(e instanceof IndexOutOfBoundsException);
}

#3 building

JUnit has built-in support for this with "expected" attribute

#4 building

JUnit 4 supports this:

@Test(expected = IndexOutOfBoundsException.class)
public void testIndexOutOfBoundsException() {

    ArrayList emptyList = new ArrayList();
    Object o = emptyList.get(0);

}

Reference resources:

#5 building

Be careful when using the expected exception because it only asserts that the method threw the exception, not a specific line of code in the test.

I tend to use it for test parameter validation because such methods are usually very simple, but it is better to use more complex tests for:

try {
    methodThatShouldThrow();
    fail( "My method didn't throw when I expected it to" );
} catch (MyException expectedException) {
}

Use judgment.

Posted by ivki on Thu, 05 Dec 2019 07:17:29 -0800