JUnit Тест очікуваного винятку: @Test(очікується)
⚡ Розумний підсумок
JUnit Тестування винятків підтверджує, що метод викидає саме ту помилку, яку він має викидати, використовуючи необов'язковий параметр expected анотації @Test у JUnit 4 та метод assertThrows у JUnit 5.
JUnit надає можливість tracвиняток, а також перевірити, чи код викидає очікуваний виняток чи ні.
JUnit 4 забезпечує простий та зрозумілий спосіб тестування винятків. Ви можете використовувати:
- Необов'язковий параметр (очікуваний) Анотація @Test та
- До tracДля отримання цієї інформації можна використовувати функцію «fail()».
У той час як Тестування виняток, вам потрібно переконатися, що клас винятку, який ви надаєте в цьому необов'язковому параметрі Анотація @Test той самий, який фактично викидає метод. Це тому, що ви очікуєте виняток від методу, який ви використовуєте одиничне тестуванняінакше наші JUnit тест буде невдалим.
Приклад: @Test(очікується = IllegalArgumentException.class)
Використовуючи параметр «očekаний», ви можете вказати назву винятку, який може викинути наш тест. У наведеному вище прикладі ви використовуєте «НезаконнийВинятокАргументу«, який буде викинуто тестом, якщо розробник використає недозволений аргумент.
Приклад використання @Test(expected)
Давайте розберемося з тестуванням винятків, створивши Java клас з методом, який викидає винятокВи будете цим займатися та тестувати в тестовому класі. Розгляньте JUnitMessage.java, у якому є метод, що виконує математичну операцію. Ділення в рядку 14 ділить на нуль, тому метод завжди викидає виняток «ArithmeticException». Див. нижче:
package guru99.junit; public class JUnitMessage{ private String message; public JUnitMessage(String message) { this.message = message; } public void printMessage(){ System.out.println(message); int divide=1/0; } public String printHiMessage(){ message="Hi!" + message; System.out.println(message); return message; } }
Code Пояснення:
- Code Лінія 7: Створення параметризованого конструктора з ініціалізацією поля.
- Code Рядок 11-14: Створення методу для математичної операції.
- Code Лінія 18: Створення іншого способу друку повідомлення.
- Code Лінія 20: Створення нового рядка для друку повідомлення.
- Code Лінія 22: Друк нового повідомлення, створеного в рядку 20.
Давайте створимо тестовий клас для вищезазначеного Java клас для перевірки винятку.
Дивіться нижче тестовий клас, який перевіряє виняток (тут ArithmeticException), що викинуто вище. Java клас:
AirthematicTest.java
На скріншоті нижче показано той самий тест у редакторі, де файл збережено як AirthematicTest1, з виділеним очікуваним параметром у рядку 13:
package guru99.junit; import static org.junit.Assert.assertEquals; import org.junit.Test; public class AirthematicTest { public String message = "Saurabh"; JUnitMessage junitMessage = new JUnitMessage(message); @Test(expected = ArithmeticException.class) public void testJUnitMessage(){ System.out.println("Junit Message is printing "); junitMessage.printMessage(); } @Test public void testJUnitHiMessage(){ message="Hi!" + message; System.out.println("Junit Message is printing "); assertEquals(message, junitMessage.printHiMessage()); } }
Code Пояснення:
- Code Лінія 13: Використання анотації @Test для створення нашого тесту. Під час виконання методу вищезгаданого класу викличеться математична операція. Тут очікується ArithmeticException, тому ви перераховуєте його як параметр у @Test.
- Code Лінія 17: Виклик printMessage() з JUnitMessage.java.
- Code Рядок 21-22: Створення ще одного тестового методу для перевірки повідомлення Hi, цього разу без очікуваного параметра.
Клас містить два методи тестування, тому один запуск виконує обидва: той, що очікує ArithmeticException, і той, що виконує ствердження для повернутого рядка.
Примітка: Цей приклад у вихідному матеріалі має три назви: у лістингу викликається клас AirthematicTest, на скріншоті редактора показано AirthematicTest1, а у вигляді результату відображається JunitTestExample. Код ідентичний у кожному випадку; відрізняється лише ім'я файлу.
Давайте виконаємо це та перевіримо результат. JUnit переглянути нижче звіти про пробіг JunitTestExample.java.
вихід:
Ось результат, який показує успішне проходження тесту без збоїв tracе., як зазначено нижче:
Обидва методи позначені зеленим. Перший проходить, оскільки оголошений ним ArithmeticException справді надійшов, а другий проходить, оскільки повернутий рядок збігся. Якби ділення ніколи не було викликано, JUnit перший метод би не виконався з повідомленням «Очікуваний виняток: java.lang.ArithmeticException».
Три способи перевірки винятку в JUnit 4
Очікуваний параметр є найкоротшим з трьох JUnit 4 ідіоми, але не завжди правильна. У таблиці їх порівнюють за двома питаннями, які визначають вибір: чи можете ви стверджувати щодо повідомлення, і чи знаєте ви, який рядок кинутий?
| Підхід | Підтверджує повідомлення? | Закріплює лінію кидка? | Найкраще для |
| @Test(очікуване = X.class) | Немає | Ні — будь-який рядок у методі може викинути | Короткі тести, де важливий лише тип винятку. |
| спробувати / невдало() / зловити | Так, всередині блоку catch | Так — відстежується лише захищений дзвінок | Тести, які мають перевірити повідомлення або причину. |
| @Rule Очікуваний виняток | Так, через expectMessage() | Немає | Застарілі пакети вже побудовані за правилами. |
Ідіома fail(), згадана у вступі, виглядає так. Якщо виклик не викликає виправлення, виконується fail(), і тест видає повідомлення, яке ви написали:
@Test public void testDivideByZero() { try { junitMessage.printMessage(); fail("Expected an ArithmeticException"); } catch (ArithmeticException e) { assertEquals("/ by zero", e.getMessage()); } }
Правило ExpectedException знаходиться між ними. Його було виключено з програми JUnit 4.13 на користь методу assertThrows, описаного далі, тобто нового JUnit 4 тести не повинні його використовувати.
Як тестувати винятки в JUnit 5 з assertThrows()
JUnit 5 повністю видаляє очікуваний параметр з @Test. Jupiter постачає assertThrows(), який приймає клас винятку та лямбда-вираз, що містить тестований код. Він повертає перехоплений виняток, тому повідомлення, причину та будь-яке користувацьке поле можна використовувати пізніше.
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; public class AirthematicJupiterTest { JUnitMessage junitMessage = new JUnitMessage("Saurabh"); @Test public void testJUnitMessage() { ArithmeticException thrown = assertThrows( ArithmeticException.class, () -> junitMessage.printMessage()); assertEquals("/ by zero", thrown.getMessage()); } }
Три пов'язані твердження доповніть родину:
- assertThrows приймає тип винятку або будь-який його підклас.
- assertThrowsExact відхиляє підклас, тому проходить лише іменований тип.
- assertDoesNotThrow стверджує протилежне очікування, що блок завершиться чисто.
Команда JUnit 4 код на цій сторінці все ще працює на JUnit Платформа через вінтажний движок, тому нічого вище не потрібно переписувати, щоб продовжувати працювати під час міграції проєкту.
Типові помилки під час тестування винятків у JUnit
Тести на винятки зазнають невдачі кількома відомими способами. У кожному рядку вказано симптом, причину та спосіб виправлення.
| симптом | Викликати | виправляти |
| Очікуваний виняток: java.lang.ArithmeticException | Метод завершено без кидання. | Перевірте, чи введені дані дійсно недійсні, а потім повторіть спробу. |
| Тест пройдено, але кинуто неправильну строчку | Очікуваний параметр спостерігає за всім методом, включаючи налаштування. | Перенесіть налаштування або перейдіть на assertThrows для одного виклику. |
| Необроблений тип винятку в редакторі | Викидається перевірений виняток, але він ніколи не оголошується. | Додайте кидки до сигнатури методу тестування. |
| Тест пройдено з підкласу, який ви не планували | assertThrows приймає підкласи іменованого типу. | Використовуйте assertThrowsExactly для суворого збігу типів. |
| очікуваний атрибут не є дійсним | Тест було скомпільовано відповідно до анотації Jupiter @Test. | Імпорт org.junit.Test для JUnit 4, або перейдіть до assertThrows. |
Останній рядок – це той, який застає більшість людей під час міграції, оскільки обидві анотації мають назву @Test, і лише імпорт їх відрізняє. Keeping один JUnit версія за тестовий випадок клас уникає всієї проблеми класу.



