Testing for multiple exceptions with JUnit 4 annotations

This is not possible with the annotation.

With JUnit 4.7 you can use the new ExpectedException rule

public static class HasExpectedException {
    @Interceptor
    public ExpectedException thrown= new ExpectedException();

    @Test
    public void throwsNothing() {
    }

    @Test
    public void throwsNullPointerException() {
         thrown.expect(NullPointerException.class);
         throw new NullPointerException();
    }

    @Test
    public void throwsNullPointerExceptionWithMessage() {
        thrown.expect(NullPointerException.class);
        thrown.expectMessage("happened?");
        throw new NullPointerException("What happened?");
    }
}

More see

  • JUnit 4.7: Interceptors: expected exceptions
  • Rules in JUnit 4.7

If updating to JUnit 4.7 is not possible for you, you have to write a bare unit test of the form

public test() {
    try {
        methodCall(); // should throw Exception
        fail();
    }
    catch (Exception ex) {
        assert((ex instanceof A) || (ex instanceof B) || ...etc...);
        ...
    }

}


Although this is not possible with JUnit 4, it is possible if you switch to TestNG, which allows you to write

@Test(expectedExceptions = {IllegalArgumentException.class, NullPointerException.class})

Use catch-exception:

// test 
public void testDo() {

   // obj.do(1) must throw either A or B
   catchException(obj).do(1);
   assert caughtException() instanceof A
       || caughtException() instanceof B;

   // obj.do(2) must throw A but not SubclassOfA
   catchException(obj).do(2);
   assert caughtException() instanceof A
       && !(caughtException() instanceof SubclassOfA);

}

You really want the test to do one thing, and to test for that. If you're not sure as to which exception is going to be thrown, that doesn't sound like a good test to me.

e.g. (in pseudo-code)

try {
   badOperation();
   /// looks like we succeeded. Not good! Fail the test
   fail();
}
catch (ExpectedException e) {
   // that's fine
}
catch (UnexpectedException e) {
   // that's NOT fine. Fail the test
}

so if you want to test that your method throws 2 different exceptions (for 2 sets of inputs), then you'll need 2 tests.