В JUnit 4.12 есть несколько способов проверить код на ожидаемые исключения.
try-catch
Мы можем просто использовать Java try-catch.
@Test
public void testInvalidData() {
prepareTestData();
try {
userService.fetchUser(1234);
Assert.fail("IllegalArgumentException not thrown");
} catch (IllegalArgumentException expected) {
}
}
Всякий раз, когда мы используем этот подход, мы должны обязательно вызывать Assert.fail(...)
, если ожидаемое исключение не было выдано.
Атрибут аннотации
Как вы уже упоминали, @Test
имеетатрибут для объявления ожидаемого исключения.
@Test(expected = IllegalArgumentException.class)
public void testInvalidData() {
prepareTestData();
// should throw IllegalArgumentException
userService.fetchUser(1234);
}
Тест зеленый, если метод теста выдает исключение.Тест красный, если метод теста не выдает ни одного исключения, или другого исключения.
У этого есть один большой недостаток: мы не можем выяснить, какая инструкция выдает исключение IllegalArgumentException.Если prepareTestData();
выдает исключение, тест остается зеленым.
Правило ExpectedException
JUnit 4 содержит встроенное правило ExpectedException.(помните, что в JUnit 5 вместо правил используются расширения)
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void testInvalidData() {
prepareTestData();
thrown.expect(IllegalArgumentException.class);
userService.fetchUser(1234);
}
Этот подход аналогичен try-catch и @Test(expected = ...)
, но мы можем контролировать, с какой точки ожидается исключение.
assertThrows
AssertJ и JUnit 5 предоставляют методы для подтверждения того, что определенный блок кода вызывает конкретное исключение.
@Test
public void testInvalidData() {
prepareTestData();
Assertions.assertThrows(IllegalArgumentException.class, () -> {
userService.fetchUser(1234);
});
}
Assertions.assertThrows
также возвращает объект исключения для выполнения дальнейших утверждений, напримерчтобы подтвердить сообщение.
Сводка
Я стараюсь использовать assertThrows
как можно чаще, потому что тестовый код становится читабельным и гибким.Но все остальные упомянутые подходы также действительны, если они используются правильно.