Checked і unchecked винятки, try-with-resources, AssertionError
Усе, що можна кинути, успадковує Throwable. Є дві гілки:
- Error — серйозні збої JVM (
OutOfMemoryError) іAssertionError, який кидають assert-бібліотеки. Їх зазвичай не ловлять. - Exception — те, що можна обробити. Checked (наприклад,
IOException,SQLException) компілятор змушує обробити чи оголосити черезthrows. Unchecked — нащадкиRuntimeException(NullPointerException,IllegalArgumentException,IndexOutOfBoundsException); обробка не обов’язкова.
Власні винятки. Для тестового коду зазвичай роблять unchecked, щоб не засмічувати сигнатури: class TestDataException extends RuntimeException. Завжди передавайте причину, щоб не втратити стек:
try {
return mapper.readValue(Files.readString(file), User.class);
} catch (IOException e) {
throw new TestDataException("Failed to load test data: " + file, e);
}
try-with-resources автоматично викликає close() для об’єктів, що реалізують AutoCloseable (потоки, з’єднання з БД, клієнти), навіть якщо стався виняток. Закриття іде у зворотному порядку відкриття; виняток із close() не затирає основний, а додається як suppressed.
Чого не робити в тестах:
- Порожній
catchчи лишеprintStackTrace(): збій зникає, тест зелений, а сценарій не виконано. catch (Throwable)чиcatch (Exception)навколо перевірок:AssertionError— цеError, тож перший варіант його проковтне (тест «пройде»), а другий не зловить і тест коректно впаде.throws Exceptionу кожному методі лише щоб відв’язатися від компілятора.
Коли ловити: коли ви справді можете відреагувати (повторна спроба, очікуваний негативний сценарій, додавання контексту). Очікувану відмову перевіряють через assertThatThrownBy(...) (AssertJ) чи assertThrows (JUnit), а не через try/catch із fail().