Я искал несколько хороших решений, однако, ни одно из решений меня не удовлетворяло. Итак, я создал свой собственный.
public final void assertThrows(VoidFunction v, Class<? extends Exception> e) {
try {
v.call();
} catch (Exception ex) {
if (!ex.getClass().equals(e)) {
Assert.fail();
}
// Do nothing, basically succeeds test if same exception was thrown.
return;
}
// Fails if no exception is thrown by default.
Assert.fail();
}
Где VoidFunction - простой интерфейс:
@FunctionalInterface
public interface VoidFunction {
void call();
}
Используется следующим образом (например):
@Test
public void testFoo() {
assertThrows(() -> foo.bar(null)), NullPointerException.class);
assertThrows(() -> foo.setPositiveInt(-5)), IllegalArgumentException.class);
assertThrows(() -> foo.getObjectAt(-100)), IndexOutOfBoundsException.class);
assertThrows(new VoidFunction() {
@Override
public void call() {
foo.getObjectAt(-100);
}
}, IndexOutOfBoundsException.class); // Success
assertThrows(new VoidFunction() {
@Override
public void call() {
throw new Exception();
}
}, NullPointerException.class); // Fail
}
Я включил один вызов без использования лямбды, это иногда облегчает понимание кода, по крайней мере, для меня.
Простой в использовании, и он позволяет несколько ловушек исключений в одном методе.