Введение в AssertJ

Введение в AssertJ

1. Overviewс

В этой статье мы рассмотримAssertJ - библиотеку с открытым исходным кодом, управляемую сообществом, используемую для написания плавных и разнообразных утверждений в тестах Java.

В этой статье рассматриваются инструменты, доступные в базовом модуле AssertJ под названиемAssertJ-core.

2. Maven Dependenciesс

Чтобы использовать AssertJ, вам необходимо включить следующий раздел в ваш файлpom.xml:


    org.assertj
    assertj-core
    3.4.1
    test

Эта зависимость охватывает только основные утверждения Java. Если вы хотите использовать расширенные утверждения, вам нужно будет добавить дополнительные модули отдельно.

Обратите внимание, что для Java 7 и более ранних версий вы должны использовать ядро ​​AssertJ версии 2.x.x.

Последние версии можно найтиhere.

3. Вступление

AssertJ предоставляет набор классов и служебных методов, которые позволяют нам легко писать беглые и красивые утверждения для:

  • Стандартная Java

  • Java 8

  • гуайява

  • Время йода

  • Neo4J и

  • Качели компонентов

Подробный список всех модулей доступен вwebsite проекта.

Начнем с нескольких примеров прямо из документации AssertJ:

assertThat(frodo)
  .isNotEqualTo(sauron)
  .isIn(fellowshipOfTheRing);

assertThat(frodo.getName())
  .startsWith("Fro")
  .endsWith("do")
  .isEqualToIgnoringCase("frodo");

assertThat(fellowshipOfTheRing)
  .hasSize(9)
  .contains(frodo, sam)
  .doesNotContain(sauron);

Приведенные выше примеры являются лишь верхушкой айсберга, но дают нам представление о том, как может выглядеть написание утверждений с помощью этой библиотеки.

4. AssertJ in Actionс

В этом разделе мы сосредоточимся на настройке AssertJ и изучении его возможностей.

4.1. Начиная

С помощью jar библиотеки на пути к классам включить утверждения так же просто, как добавить один статический импорт в ваш тестовый класс:

import static org.assertj.core.api.Assertions.*;

4.2. Написание утверждений

Чтобы написать утверждение, вам всегда нужно начинать с передачи вашего объекта методуAssertions.assertThat(), а затем следовать фактическим утверждениям.

Важно помнить, что в отличие от некоторых других библиотек, приведенный ниже код на самом деле еще ничего не утверждает иnever не пройдёт тест:

assertThat(anyRefenceOrValue);

Если вы используете функции автозавершения кода своей IDE, написание утверждений AssertJ станет невероятно простым из-за его очень наглядных методов. Вот как это выглядит в IntelliJ IDEA 16:

IDE’s code completion features

Функции автозавершения кода IDE

 

Как видите, у вас есть десятки контекстных методов на выбор, и они доступны только для типаString. Давайте подробно рассмотрим некоторые из этих API и рассмотрим некоторые конкретные утверждения.

4.3. Object Утверждения

Objects можно сравнивать различными способами: либо для определения равенства двух объектов, либо для проверки полей объекта.

Давайте рассмотрим два способа сравнить равенство двух объектов. Учитывая следующие два объектаDogfido иfidosClone:

public class Dog {
    private String name;
    private Float weight;

    // standard getters and setters
}

Dog fido = new Dog("Fido", 5.25);

Dog fidosClone = new Dog("Fido", 5.25);

Мы можем сравнить равенство со следующим утверждением:

assertThat(fido).isEqualTo(fidosClone);

Это не удастся, посколькуisEqualTo() сравнивает ссылки на объекты. Если вместо этого мы хотим сравнить их содержимое, мы можем использоватьisEqualToComparingFieldByFieldRecursively() следующим образом:

assertThat(fido).isEqualToComparingFieldByFieldRecursively(fidosClone);

Fido иfidosClone равны при выполнении рекурсивного поля путем сравнения полей, потому что каждое поле одного объекта сравнивается с полем другого объекта.

Существует много других методов утверждений, которые предоставляют различные способы сравнения и сжатия объектов, а также проверки и утверждения их полей. Чтобы узнать их все, обратитесь к официальномуAbstractObjectAssertdocumentation.

4.4. Boolean Утверждения

Существует несколько простых методов проверки правдивости:

  • правда()

  • isFalse ()

Давайте посмотрим на них в действии:

assertThat("".isEmpty()).isTrue();

4.5. Iterable/Array Утверждения

ДляIterable илиArray существует несколько способов подтвердить, что их содержимое существует. Одно из наиболее распространенных утверждений - проверить, содержит лиIterable илиArray заданный элемент:

List list = Arrays.asList("1", "2", "3");

assertThat(list).contains("1");

или еслиList не пуст:

assertThat(list).isNotEmpty();

или еслиList начинается с данного символа. Например, «1»:

assertThat(list).startsWith("1");

Помните, что если вы хотите создать более одного утверждения для одного и того же объекта, вы можете легко объединить их.

Вот пример утверждения, которое проверяет, является ли предоставленный список не пустым, содержит ли элемент «1», не содержит ли он нулей и содержит ли последовательность элементов «2», «3»:

assertThat(list)
  .isNotEmpty()
  .contains("1")
  .doesNotContainNull()
  .containsSequence("2", "3");

Конечно, существует много других возможных утверждений для этих типов. Чтобы узнать их все, обратитесь к официальномуAbstractIterableAssertdocumentation.

4.6. Character Утверждения

Утверждения для типов символов в основном включают сравнения и даже проверку того, взят ли данный символ из таблицыUnicode.

Вот пример утверждения, которое проверяет, является ли предоставленный символ не «a», находится ли в таблице Unicode, больше, чем «b» и строчные буквы:

assertThat(someCharacter)
  .isNotEqualTo('a')
  .inUnicode()
  .isGreaterThanOrEqualTo('b')
  .isLowerCase();

Подробный список утверждений всех типов символов см. ВAbstractCharacterAssertdocumentation.

4.7. Class Утверждения

Утверждения для типаClass в основном касаются проверки его полей, типовClass, наличия аннотаций и завершенности класса.

Если вы хотите утверждать, что классRunnable является интерфейсом, вам нужно просто написать:

assertThat(Runnable.class).isInterface();

или если вы хотите проверить, назначается ли один класс из другого:

assertThat(Exception.class).isAssignableFrom(NoSuchElementException.class);

Все возможные утвержденияClass можно просмотреть вAbstractClassAssertdocumentation.

4.8. File Утверждения

УтвержденияFile предназначены для проверки того, существует ли данный экземплярFile, является ли он каталогом или файлом, имеет ли определенное содержимое, доступен для чтения или имеет ли расширение.

Здесь вы можете увидеть пример утверждения, которое проверяет, существует ли данный файл, является ли он файлом, а не каталогом, может ли он быть доступен для чтения и записи:

 assertThat(someFile)
   .exists()
   .isFile()
   .canRead()
   .canWrite();

Все возможные утверждения класса можно просмотреть вAbstractFileAssertdocumentation.

4.9. Double/Float/Integer Утверждения

Double/Float/Integer и другие типыNumber

Числовые утверждения все о сравнении числовых значений в пределах или без заданного смещения. Например, если вы хотите проверить, равны ли два значения в соответствии с заданной точностью, мы можем сделать следующее:

assertThat(5.1).isEqualTo(5, withPrecision(1d));

Обратите внимание, что мы используем уже импортированный вспомогательный методwithPrecision(Double offset) для создания объектовOffset.

Для получения дополнительных утверждений посетите AbstractDoubleAssertdocumentation.

4.10. InputStream Утверждения

Доступно только одно специфичное дляInputStream утверждение:

  • hasSameContentAs (ожидается InputStream)

и в действии:

assertThat(given).hasSameContentAs(expected);

4.11. Map Утверждения

УтвержденияMap позволяют вам проверить, содержит ли карта определенную запись, набор записей или ключи / значения по отдельности.

И здесь вы можете увидеть пример утверждения, которое проверяет, не является ли данная карта пустой, содержит ли числовой ключ «2», не содержит числовой ключ «10» и содержит запись:key: 2, value: “a”:

assertThat(map)
  .isNotEmpty()
  .containsKey(2)
  .doesNotContainKeys(10)
  .contains(entry(2, "a"));

Дополнительные утверждения см. ВAbstractMapAssertdocumentation.

4.12. Throwable Утверждения

УтвержденияThrowable позволяют, например: проверять сообщения об исключении, трассировку стека, проверять причины или проверять, было ли уже создано исключение.

Давайте посмотрим на пример утверждения, которое проверяет, было ли выброшено данное исключение, и имеет ли сообщение, заканчивающееся на «c»:

assertThat(ex).hasNoCause().hasMessageEndingWith("c");

Для получения дополнительных утверждений см. AbstractThrowableAssertdocumentation.

5. Описание утверждений

Чтобы достичь еще более высокого уровня детализации, вы можете создавать динамически генерируемые пользовательские описания для ваших утверждений. Ключом к этому является методas(String description, Object… args).

Если вы определите свое утверждение так:

assertThat(person.getAge())
  .as("%s's age should be equal to 100", person.getName())
  .isEqualTo(100);

вот что вы получите при запуске тестов:

[Alex's age should be equal to 100] expected:<100> but was:(34)

6. Java 8

AssertJ в полной мере использует возможности функционального программирования Java 8. Давайте рассмотрим пример и посмотрим, как он работает. Сначала давайте посмотрим, как мы это делаем в Java 7:

assertThat(fellowshipOfTheRing)
  .filteredOn("race", HOBBIT)
  .containsOnly(sam, frodo, pippin, merry);

Здесь мы фильтруем коллекцию по расе Хоббит и в Java 8 мы можем сделать что-то вроде этого:

assertThat(fellowshipOfTheRing)
  .filteredOn(character -> character.getRace().equals(HOBBIT))
  .containsOnly(sam, frodo, pippin, merry);

Мы будем исследовать возможности Java8 в AssertJ в следующей статье из этой серии. Приведенные выше примеры были взяты из AssertJ’swebsite.

7. Conclusionс

В этой статье мы кратко рассмотрели возможности, которые AssertJ предоставляет нам вместе с наиболее популярными утверждениями для основных типов Java.

Реализацию всех примеров и фрагментов кода можно найти вGitHub project.