← Назад к вопросам
Как проверить ожидаемое исключение в JUnit
1.0 Junior🔥 251 комментариев
#Тестирование
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Проверка ожидаемого исключения в JUnit
В JUnit существует несколько способов проверить, что код выбросит ожидаемое исключение. Это критически важный навык для написания надежных тестов.
1. Аннотация @Test(expected = Exception.class) - JUnit 4
Самый простой способ для JUnit 4:
@Test(expected = NullPointerException.class)
public void testNullPointerException() {
String str = null;
str.length(); // выбросит NullPointerException
}
2. ExpectedException Rule - JUnit 4
Более гибкий подход с дополнительными проверками:
@Rule
public ExpectedException exceptionRule = ExpectedException.none();
@Test
public void testWithExpectedException() {
exceptionRule.expect(IllegalArgumentException.class);
exceptionRule.expectMessage("Age must be positive");
validateAge(-5); // выбросит исключение
}
3. assertThrows() - JUnit 5 (современный подход)
Рекомендуемый способ в JUnit 5:
@Test
void testDivisionByZero() {
assertThrows(ArithmeticException.class, () -> {
int result = 10 / 0;
});
}
С проверкой сообщения об ошибке:
@Test
void testWithMessage() {
ArithmeticException exception = assertThrows(
ArithmeticException.class,
() -> { int result = 10 / 0; }
);
assertEquals("/ by zero", exception.getMessage());
}
4. assertThrowsExactly() - JUnit 5.8+
Для проверки точного типа исключения (без подклассов):
@Test
void testExactException() {
assertThrowsExactly(
IllegalArgumentException.class,
() -> { throw new IllegalArgumentException("Invalid"); }
);
}
5. Try-Catch с Assertions (классический подход)
Для большей гибкости:
@Test
public void testWithTryCatch() {
try {
riskyOperation();
fail("Should have thrown an exception");
} catch (CustomException e) {
assertEquals("Expected message", e.getMessage());
assertEquals(42, e.getErrorCode());
}
}
6. Проверка иерархии исключений
@Test
void testInheritance() {
// assertThrows проверяет совместимость типов
assertThrows(IOException.class, () -> {
throw new FileNotFoundException("Not found"); // подкласс IOException
});
}
Сравнение подходов
| Подход | JUnit версия | Гибкость | Рекомендация |
|---|---|---|---|
| @Test(expected) | 4 | Низкая | Устаревший |
| ExpectedException | 4 | Средняя | Для JUnit 4 |
| assertThrows() | 5 | Высокая | Современный стандарт |
| Try-Catch | Все | Высокая | Для сложных случаев |
Лучшие практики
- Используйте assertThrows() в JUnit 5 - это современный стандарт
- Всегда проверяйте сообщение об ошибке, не только тип исключения
- Оборачивайте только строку кода, которая должна выбросить исключение:
// ❌ Неправильно - слишком широкий scope
assertThrows(NullPointerException.class, () -> {
String str = null;
System.out.println("test");
str.length();
});
// ✅ Правильно - минимальный scope
assertThrows(NullPointerException.class, () -> {
String str = null;
str.length();
});
Полный пример теста
@Test
void testInvalidAgeThrowsException() {
IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> new User().setAge(-5)
);
assertTrue(exception.getMessage().contains("Age must be"));
}
Вывод: в современных проектах используйте assertThrows() из JUnit 5 - это самый читаемый и гибкий способ проверки исключений.