Є проект, про який мені стало відомо після створення цієї відповіді, яка виглядає багатообіцяючою, це вилов-виняток .
Як йдеться в описі проекту, він дозволяє кодеру записати вільний рядок коду, що виловлює виняток, і запропонує цей виняток для останнього твердження. І ви можете використовувати будь-яку бібліотеку тверджень, як-от Hamcrest або AssertJ .
Швидкий приклад з домашньої сторінки:
// given: an empty list
List myList = new ArrayList();
// when: we try to get the first element of the list
when(myList).get(1);
// then: we expect an IndexOutOfBoundsException
then(caughtException())
.isInstanceOf(IndexOutOfBoundsException.class)
.hasMessage("Index: 1, Size: 0")
.hasNoCause();
Як ви бачите, що код справді простий, ви then
виберете виняток у певному рядку, API - псевдонім, який використовуватиме API APIrtrt (подібний до використання assertThat(ex).hasNoCause()...
). У якийсь момент проект покладався на FEST-Assert, родоначальника AssertJ . EDIT: Схоже, що проект готує підтримку Java 8 Lambdas.
Наразі ця бібліотека має два недоліки:
На момент написання цього документу варто звернути увагу на те, що ця бібліотека базується на Mockito 1.x, оскільки вона створює знущання над тестуваним об’єктом за сценою. Оскільки Mockito все ще не оновлюється, ця бібліотека не може працювати з заключними класами чи заключними методами . І навіть якщо він базувався на Mockito 2 в поточній версії, для цього потрібно було б оголосити глобального макетодавця ( inline-mock-maker
), що може бути не тим, що ви хочете, оскільки цей макет-виробник має інші недоліки, ніж звичайний виробник макетів.
Це вимагає ще однієї залежності від тесту.
Ці питання не застосовуватимуться, коли бібліотека підтримує лямбда. Однак функціонал буде дублюватися набором інструментів AssertJ.
Беручи все до уваги , якщо ви не хочете використовувати інструмент всеосяжної виняток, я буду рекомендувати хороший старий шлях try
- catch
блок, по крайней мере , до JDK7. А для користувачів JDK 8 ви можете скористатися AssertJ, оскільки він пропонує, можливо, більше, ніж просто стверджувати винятки.
З JDK8 лямбди виходять на тестову сцену, і вони виявились цікавим способом стверджувати про виняткову поведінку. AssertJ був оновлений, щоб забезпечити приємний вільний API для затвердження виняткової поведінки.
І зразок тесту з AssertJ :
@Test
public void test_exception_approach_1() {
...
assertThatExceptionOfType(IOException.class)
.isThrownBy(() -> someBadIOOperation())
.withMessage("boom!");
}
@Test
public void test_exception_approach_2() {
...
assertThatThrownBy(() -> someBadIOOperation())
.isInstanceOf(Exception.class)
.hasMessageContaining("boom");
}
@Test
public void test_exception_approach_3() {
...
// when
Throwable thrown = catchThrowable(() -> someBadIOOperation());
// then
assertThat(thrown).isInstanceOf(Exception.class)
.hasMessageContaining("boom");
}
З майже повним перезаписом JUnit 5 твердження було трохи вдосконалено , вони можуть виявитись цікавими як спосіб нестандартного твердження виключення. Але насправді API твердження все ще трохи бідний, зовні нічого немає assertThrows
.
@Test
@DisplayName("throws EmptyStackException when peeked")
void throwsExceptionWhenPeeked() {
Throwable t = assertThrows(EmptyStackException.class, () -> stack.peek());
Assertions.assertEquals("...", t.getMessage());
}
Як ви помітили assertEquals
, все ще повертається void
, і як таке не дозволяє ланцюжок тверджень типу AssertJ.
Також якщо ви пам’ятаєте зіткнення імені з Matcher
або Assert
, будьте готові до зустрічі з тим самим зіткненням Assertions
.
org.mockito.Mockito.verify
з різними параметрами, щоб переконатися, що певні речі траплялися (наприклад, виклик служби реєстратора з правильними параметрами) перед тим, як викид був викинутий.