Чи можете ви додати власне повідомлення до AssertJ assertThat?


90

У нас є набір тестів, який в основному використовує твердження JUnit з відповідниками Hamcrest. Один із нашої команди почав експериментувати з AssertJ і вразив людей своїм синтаксисом, гнучкістю та декларативністю. Є одна особливість, яку надає JUnit, і я не можу знайти еквівалент в AssertJ: додавання власного повідомлення про помилку затвердження.

Ми часто порівнюємо об’єкти, які створені не для людської читабельності та мають випадкові ідентифікатори або UUID, і за даними, які вони містять, неможливо визначити, якими вони повинні бути. На жаль, це неминуча ситуація для нашої кодової бази, на жаль, оскільки частина цілі, яку вона виконує, - це зіставлення даних між іншими службами, не обов'язково розуміючи, що це таке.

У JUnit assertThatметод надає версію з String reasonпараметром перед Matcher<T>параметром. Це робить тривіальним додавання короткого рядка налагодження, який проливає деяке світло на проблему, наприклад, те, що порівняння повинно означати для людини.

AssertJ, навпаки, забезпечує мільйон різних узагальненихstatic assertThat методів, які повертають якусь форму інтерфейсу Assert або один із багатьох його реалізаційних класів. Цей інтерфейс не забезпечує стандартний спосіб встановлення користувацького повідомлення, яке включатиметься у разі помилок.

Чи є спосіб отримати цю функціональність від API AssertJ або одного з його розширень без необхідності створювати власний клас затвердження для кожного типу затвердження, до якого ми хочемо додавати повідомлення?

Відповіді:


137

І класичним способом я знайшов те, що шукав, через кілька хвилин після публікації запитання. Сподіваємось, це полегшить пошук наступній людині без необхідності знати, як це називається. Чарівний метод - оманливо коротко названий as, який є частиною іншого інтерфейсу, який AbstractAssertреалізує: Опис , а не базовий інтерфейс Assert.

public S as(String description, Object... args)

Встановлює опис цього об’єкта, що підтримує String.format(String, Object...)синтаксис.
Приклад:

try {
  // set a bad age to Mr Frodo which is really 33 years old.
  frodo.setAge(50);
  // you can specify a test description with as() method or describedAs(), it supports String format args
  assertThat(frodo.getAge()).as("check %s's age", frodo.getName()).isEqualTo(33);
} catch (AssertionError e) {
  assertThat(e).hasMessage("[check Frodo's age] expected:<[33]> but was:<[50]>");
}

Де цей рядок із цитуваннями в блоці catch hasMessage- це те, що відображається у вашому журналі вихідних даних тесту, якщо твердження не вдається.


Я знайшов це, помітивши failWithMessageпомічника на користувацькій сторінці затвердження, на яку посилається запитання. JavaDoc для цього методу вказує на те , що він захищений, тому він не може використовуватися абонентами для установки спеціального повідомлення. Однак там згадується asпомічник:

Більше того, цей метод вшановує будь-який опис, встановлений as(String, Object...)або замінений повідомленням про помилку, визначеним користувачем overridingErrorMessage(String, Object...).

... і overridingErrorMessage помічник, який повністю замінює стандартний AssertJ expected: ... but was:...повідомлення з новим рядком , зазначеної.

На домашній сторінці AssertJ не згадується жоден помічник, поки не буде виділена сторінка функцій, яка показує приклади asпомічника в розділі Soft Assertions , але прямо не описує, що він робить.


23

Щоб додати ще один варіант до відповіді Патріка М:

Замість того, щоб використовувати Descriptable.as, ви також можете використовувати AbstractAssert.withFailMessage():

try {
  // set a bad age to Mr Frodo which is really 33 years old.
  frodo.setAge(50);
  // you can specify a test description via withFailMessage(), supports String format args
  assertThat(frodo.getAge()).
    withFailMessage("Frodo's age is wrong: %s years, difference %s years",
      frodo.getAge(), frodo.getAge()-33).
    isEqualTo(33);
} catch (AssertionError e) {
  assertThat(e).hasMessage("Frodo's age is wrong: 50 years, difference 17 years");
}

Різниця у використанні Descriptable.asполягає в тому, що воно дає вам повний контроль над користувацьким повідомленням - немає "очікуваного" та "але було".

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


Зверніть увагу, що так само Descriptable.as, як і вам, потрібно телефонувати withFailMessage() перед будь-якими фактичними твердженнями - інакше це не спрацює, оскільки твердження активується першим. Це зазначається в Javadoc.


3
"Ви повинні зателефонувати withFailMessage () перед будь-якими фактичними твердженнями" дякую, це мене спокусило . Порядок виклику withFailMessageречовини; Мені подобається AssertJ, але це відмовно.
Абхіджіт Саркар


0

Використовуйте вбудований as()метод у AssertJ. Наприклад:

 assertThat(myTest).as("The test microservice is not active").isEqualTo("active");
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.