«1. Обзор
В этой статье мы рассмотрим AssertJ — управляемую сообществом библиотеку с открытым исходным кодом, используемую для написания плавных и насыщенных утверждений в тестах Java.
Эта статья посвящена инструментам, доступным в базовом модуле AssertJ под названием AssertJ-core.
2. Зависимости Maven
Чтобы использовать AssertJ, вам необходимо включить следующий раздел в ваш файл pom.xml:
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.4.1</version>
<scope>test</scope>
</dependency>
Эта зависимость охватывает только основные утверждения Java. Если вы хотите использовать расширенные утверждения, вам нужно будет добавить дополнительные модули отдельно.
Обратите внимание, что для Java 7 и более ранних версий следует использовать ядро AssertJ версии 2.x.x.
Последние версии можно найти здесь.
3. Введение
AssertJ предоставляет набор классов и служебных методов, которые позволяют нам легко писать плавные и красивые утверждения для:
-
Стандартной Java Java 8 Guava Joda Time Neo4J и компонентов Swing
Подробный список всех модулей доступен на сайте проекта.
Давайте начнем с нескольких примеров, взятых прямо из документации 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 в действии
В этом разделе мы сосредоточимся на настройке AssertJ и изучении его возможностей.
4.1. Приступая к работе
С jar библиотеки в пути к классам включить утверждения так же просто, как добавить один статический импорт в ваш тестовый класс:
import static org.assertj.core.api.Assertions.*;
4.2. Написание утверждений
Чтобы написать утверждение, вам всегда нужно начинать с передачи вашего объекта методу Assertions.assertThat(), а затем следовать фактическим утверждениям.
Важно помнить, что, в отличие от некоторых других библиотек, приведенный ниже код на самом деле еще ничего не утверждает и никогда не провалит тест:
assertThat(anyRefenceOrValue);
Если вы используете функции завершения кода вашей IDE, написание утверждений AssertJ становится невероятно простым из-за его очень описательных методов. Вот как это выглядит в IntelliJ IDEA 16:
Как видите, у вас есть десятки контекстных методов на выбор, и они доступны только для типа String. Давайте подробно рассмотрим некоторые из этих API и рассмотрим некоторые конкретные утверждения.
4.3. Утверждения объекта
Объекты можно сравнивать различными способами либо для определения равенства двух объектов, либо для проверки полей объекта.
Давайте рассмотрим два способа сравнения двух объектов на равенство. Учитывая следующие два объекта Dog fido и 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);
Это не удастся, так как isEqualTo() сравнивает ссылки на объекты. Если вместо этого мы хотим сравнить их содержимое, мы можем использовать isEqualToComparingFieldByFieldRecursively() следующим образом: другой объект.
assertThat(fido).isEqualTo(fidosClone);
Существует много других методов утверждений, которые предоставляют разные способы сравнения и сжатия объектов, а также проверки и утверждения их полей. Чтобы узнать их все, обратитесь к официальной документации AbstractObjectAssert.
assertThat(fido).isEqualToComparingFieldByFieldRecursively(fidosClone);
4.4. Логические утверждения
Для проверки истинности существует несколько простых методов:
isTrue() isFalse()
Давайте посмотрим на них в действии:
-
4.5. Утверждения Iterable/Array
Для Iterable или Array существует несколько способов подтверждения того, что их содержимое существует. Одним из наиболее распространенных утверждений будет проверка того, содержит ли Iterable или Array заданный элемент:
assertThat("".isEmpty()).isTrue();
или список не пуст:
или список начинается с заданного символа. Например, «1» :
List<String> list = Arrays.asList("1", "2", "3");
assertThat(list).contains("1");
Имейте в виду, что если вы хотите создать более одного утверждения для одного и того же объекта, вы можете легко соединить их вместе.
assertThat(list).isNotEmpty();
Вот пример утверждения, которое проверяет, не является ли предоставленный список пустым, содержит элемент «1», не содержит нулей и содержит последовательность элементов «2», «3»:
assertThat(list).startsWith("1");
«
«Конечно, для этих типов существует гораздо больше возможных утверждений. Чтобы узнать их все, обратитесь к официальной документации AbstractIterableAssert.
assertThat(list)
.isNotEmpty()
.contains("1")
.doesNotContainNull()
.containsSequence("2", "3");
4.6. Утверждения символов
Утверждения для типов символов в основном включают в себя сравнения и даже проверку того, взят ли данный символ из таблицы Unicode.
Вот пример утверждения, которое проверяет, не является ли указанный символ «a», находится ли он в таблице Unicode, больше ли «b» и является ли он строчным:
Для подробного список утверждений всех типов символов, см. документацию AbstractCharacterAssert.
assertThat(someCharacter)
.isNotEqualTo('a')
.inUnicode()
.isGreaterThanOrEqualTo('b')
.isLowerCase();
4.7. Утверждения класса
Утверждения для типа класса в основном касаются проверки его полей, типов класса, наличия аннотаций и окончательности класса.
Если вы хотите утверждать, что класс Runnable является интерфейсом, вам нужно просто написать:
или если вы хотите проверить, можно ли назначить один класс из другого:
assertThat(Runnable.class).isInterface();
Все возможные Утверждения класса можно просмотреть в документации AbstractClassAssert.
assertThat(Exception.class).isAssignableFrom(NoSuchElementException.class);
4.8. Утверждения файла
Утверждения файла связаны с проверкой того, существует ли данный экземпляр файла, является ли он каталогом или файлом, имеет ли определенное содержимое, доступен для чтения или имеет заданное расширение.
Здесь вы можете увидеть пример утверждения, которое проверяет, существует ли данный файл, является ли он файлом, а не каталогом, доступен ли он для чтения и записи:
Все возможные утверждения класса можно просмотреть в документации AbstractFileAssert .
assertThat(someFile)
.exists()
.isFile()
.canRead()
.canWrite();
4.9. Утверждения Double/Float/Integer
Double/Float/Integer и другие типы чисел
Численные утверждения предназначены для сравнения числовых значений в пределах или без заданного смещения. Например, если вы хотите проверить, равны ли два значения в соответствии с заданной точностью, мы можем сделать следующее:
Обратите внимание, что мы используем уже импортированный вспомогательный метод withPrecision(Double offset) для создания объектов Offset.
assertThat(5.1).isEqualTo(5, withPrecision(1d));
Дополнительные утверждения см. в документации по AbstractDoubleAssert.
4.10. Утверждения InputStream
Доступно только одно утверждение, специфичное для InputStream:
hasSameContentAs(ожидаемый InputStream)
-
и в действии:
4.11. Утверждения карты
assertThat(given).hasSameContentAs(expected);
Утверждения карты позволяют проверить, содержит ли карта определенную запись, набор записей или ключи/значения по отдельности.
А здесь вы можете увидеть пример утверждения, которое проверяет, не является ли данная карта пустой, содержит ли числовой ключ «2», не содержит ли числовой ключ «10» и содержит ли запись: ключ: 2, значение: «a» :
Дополнительные утверждения см. в документации по AbstractMapAssert.
assertThat(map)
.isNotEmpty()
.containsKey(2)
.doesNotContainKeys(10)
.contains(entry(2, "a"));
4.12. Выбрасываемые утверждения
Выбрасываемые утверждения позволяют, например: проверять сообщения об исключениях, трассировки стека, проверять причины или проверять, было ли уже выброшено исключение.
Давайте рассмотрим пример утверждения, которое проверяет, было ли выброшено данное исключение, и имеет ли сообщение, оканчивающееся на «c»:
Дополнительные утверждения см. в документации по AbstractThrowableAssert.
assertThat(ex).hasNoCause().hasMessageEndingWith("c");
5. Описание утверждений
Для достижения еще более высокого уровня детализации вы можете создавать динамически генерируемые пользовательские описания для своих утверждений. Ключом к этому является метод as(String description, Object… args).
Если вы определите утверждение следующим образом:
вот что вы получите при выполнении тестов:
assertThat(person.getAge())
.as("%s's age should be equal to 100", person.getName())
.isEqualTo(100);
6. Java 8
[Alex's age should be equal to 100] expected:<100> but was:<34>
AssertJ в полной мере использует возможности функционального программирования Java 8. . Давайте погрузимся в пример и посмотрим его в действии. Сначала давайте посмотрим, как мы это делаем в Java 7:
Здесь мы фильтруем коллекцию на расе Hobbit, а в Java 8 мы можем сделать что-то вроде этого:
assertThat(fellowshipOfTheRing)
.filteredOn("race", HOBBIT)
.containsOnly(sam, frodo, pippin, merry);
Мы будем изучать Java8 AssertJ. возможности в будущей статье из этой серии. Приведенные выше примеры были взяты с веб-сайта AssertJ.
assertThat(fellowshipOfTheRing)
.filteredOn(character -> character.getRace().equals(HOBBIT))
.containsOnly(sam, frodo, pippin, merry);
7. Заключение
В этой статье мы кратко рассмотрели возможности, которые дает нам AssertJ, наряду с наиболее популярными утверждениями для основных типов Java.
Реализацию всех примеров и фрагментов кода можно найти в проекте GitHub.
«