← Назад к вопросам

Как проверить ожидаемое исключение в 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НизкаяУстаревший
ExpectedException4СредняяДля 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 - это самый читаемый и гибкий способ проверки исключений.