У junit перевіряти очікувані виключення • а хочете, я розповім вам

Іноді виникнення виключення є очікуваним поведінкою системи, і в тестах потрібно перевіряти, що воно дійсно виникає.

Нижче описані п'ять способів, як в тестовому фреймворку JUnit перехопити очікуване виняток і перевірити його властивості. Перші чотири з них можна використовувати в JUnit 4, а останній спосіб використовує нові можливості JUnit 5.

Як приклад для демонстрації візьмемо тест для функції стандартної бібліотеки, що створює тимчасовий файл. Будемо перевіряти, що при спробі створення файлу в неіснуючої директорії виникає виняток типу IOException. При цьому попередньо в тому ж самому тесті створюється тимчасова директорія і тут же видаляється, так що ми отримуємо гарантовано неіснуючу директорію, в якій і намагаємося створити файл:

Зрозуміло, в такому вигляді тест впаде, а в звіті буде написано, що виникло виключення. А нам потрібно, щоб тест в цьому випадку навпаки позначався як успішний. Подивимося, як це можна виправити.

Найпростіший спосіб повідомити тестовому фреймворку про те, що очікується виняток - вказати додатковий параметр expected в анотації @Test:

Цей параметр повинен містити тип очікуваного виключення. Якщо виникне виключення саме такого типу - тест пройде успішно. Якщо виникне виключення іншого типу або не виникне зовсім - тест впаде.

  • Не можна перевірити текст повідомлення або інші властивості виник виключення.
  • Не можна зрозуміти, де саме виникло виключення. У розглянутому прикладі воно могло бути викинуто НЕ тестируемой функцією, а трохи раніше, при спробі створити тимчасову директорію. Тест навіть не зміг дістатися до виклику тестируемой функції - але при цьому в звіті він позначається як успішно пройдений!

Друга зі згаданих проблем настільки жахлива, що я нікому ніколи не рекомендую використовувати цей спосіб.

2. try-catch

Обидва нестачі можна усунути, якщо перехоплювати виключення явно за допомогою конструкції try-catch:

Якщо виключення виникає до блоку try - тест падає, ми дізнаємося про те, що у нього виникли проблеми.

Якщо тестована функція не викидає взагалі ніякого виключення - ми потрапляємо на fail () в наступному рядку, тест падає.

Якщо вона викидає виключення невідповідного типу - блок catch не ловить його, тест знову таки падає.

Успішно він завершується тільки тоді, коли тестована функція викидає виключення потрібного типу.

Тест став більш надійним, він більше не пропускає баги. А в блоці catch можна перевірити властивості спійманого виключення.

Однак працювати з конструкцією try-catch незручно.

Щоб позбутися від неї, можна скористатися правилом ExpectedException. входять в стандартний дистрибутив JUnit 4:

Тепер код має просту плоску структуру, хоча загальна кількість рядків коду, на жаль, збільшилася.

Але головна проблема цього способу полягає в тому, що перевірки в такому стилі виглядають протиприродно - спочатку описується поведінка, а потім викликається функція. Звичайно, це справа смаку, але мені подобається, коли перевірки розташовуються після виклику тестируемой функції.

4. AssertJ / catch-throwable

Більш красивий спосіб, який використовує можливості Java 8, пропонують додаткові бібліотеки, такі як AssertJ або catch-throwable. Ось приклад роботи з AssertJ:

А якщо виняток не виникне - "пастка" сама викине виняток і тест впаде.

5. JUnit 5

Але чому потрібно використовувати якісь додаткові бібліотеки, чому тестові фреймворки самі не пропонують зручних можливостей для роботи з очікуваними винятками?

Уже надають. Перехоплення винятків в JUnit 5 виглядає дуже схоже на попередній приклад:

Раніше така можливість в JUnit була відсутня, тому що попередні версії JUnit були орієнтовані на більш старі версії Java, де не було лямбда-виразів і написати подібний код було просто неможливо. Так, можна зробити щось подібне за допомогою анонімних класів, але це виглядає настільки жахливо, що конструкція try-catch здається верхом витонченості.

Так що якщо вам доводиться писати тести, в яких перевіряється виникнення виключень - є привід придивитися до нових можливостей JUnit 5.

У junit перевіряти очікувані виключення • а хочете, я розповім вам

Share on Twitter Share on Facebook Share on Google+