1. Обзор
В этом руководстве мы рассмотрим создание пользовательских утверждений AssertJ; основы AssertJ можно найти здесь.
Проще говоря, пользовательские утверждения позволяют создавать утверждения, характерные для наших собственных классов, что позволяет нашим тестам лучше отражать модель предметной области.
2. Тестируемый класс
Тестовые примеры в этом руководстве будут построены вокруг класса Person:
3. Пользовательский класс утверждений
public class Person {
private String fullName;
private int age;
private List<String> nicknames;
public Person(String fullName, int age) {
this.fullName = fullName;
this.age = age;
this.nicknames = new ArrayList<>();
}
public void addNickname(String nickname) {
nicknames.add(nickname);
}
// getters
}
Написать собственный класс утверждений AssertJ довольно просто. Все, что нам нужно сделать, это объявить класс, который расширяет AbstractAssert, добавить необходимый конструктор и предоставить пользовательские методы утверждения.
Класс утверждений должен расширять класс AbstractAssert, чтобы предоставить нам доступ к основным методам утверждений API, таким как isNotNull и isEqualTo.
Вот скелет пользовательского класса утверждений для Person:
При расширении класса AbstractAssert мы должны указать два аргумента типа: первый — это сам собственный класс утверждений, который требуется для цепочки методов, и во-вторых, это тестируемый класс.
public class PersonAssert extends AbstractAssert<PersonAssert, Person> {
public PersonAssert(Person actual) {
super(actual, PersonAssert.class);
}
// assertion methods described later
}
Чтобы предоставить точку входа в наш класс утверждений, мы можем определить статический метод, который можно использовать для запуска цепочки утверждений:
Далее мы рассмотрим несколько пользовательских утверждений, включенных в класс PersonAssert. .
public static PersonAssert assertThat(Person actual) {
return new PersonAssert(actual);
}
Первый метод проверяет, соответствует ли полное имя человека строковому аргументу:
Следующий метод проверяет, является ли человек взрослым, основываясь на его возрасте:
public PersonAssert hasFullName(String fullName) {
isNotNull();
if (!actual.getFullName().equals(fullName)) {
failWithMessage("Expected person to have full name %s but was %s",
fullName, actual.getFullName());
}
return this;
}
Последний проверяет наличие существование псевдонима:
public PersonAssert isAdult() {
isNotNull();
if (actual.getAge() < 18) {
failWithMessage("Expected person to be adult");
}
return this;
}
При наличии более одного пользовательского класса утверждений мы можем обернуть все методы assertThat в класс, предоставив статический фабричный метод для каждого из классов утверждений:
public PersonAssert hasNickName(String nickName) {
isNotNull();
if (!actual.getNickNames().contains(nickName)) {
failWithMessage("Expected person to have nickname %s",
nickName);
}
return this;
}
Показанный выше класс утверждений является удобной точкой входа для всех пользовательских классов утверждений.
public class Assertions {
public static PersonAssert assertThat(Person actual) {
return new PersonAssert(actual);
}
// static factory methods of other assertion classes
}
Статические методы этого класса имеют одинаковые имена и отличаются друг от друга типом параметра.
4. В действии
Следующие тестовые примеры иллюстрируют пользовательские методы утверждений, которые мы создали в предыдущем разделе. Обратите внимание, что метод assertThat импортируется из нашего пользовательского класса Assertions, а не из основного API AssertJ.
Вот как можно использовать метод hasFullName:
Это отрицательный тестовый пример, иллюстрирующий метод isAdult:
@Test
public void whenPersonNameMatches_thenCorrect() {
Person person = new Person("John Doe", 20);
assertThat(person)
.hasFullName("John Doe");
}
и еще один тест, демонстрирующий метод hasNickname:
@Test
public void whenPersonAgeLessThanEighteen_thenNotAdult() {
Person person = new Person("Jane Roe", 16);
// assertion fails
assertThat(person).isAdult();
}
5 .Генератор утверждений
@Test
public void whenPersonDoesNotHaveAMatchingNickname_thenIncorrect() {
Person person = new Person("John Doe", 20);
person.addNickname("Nick");
// assertion will fail
assertThat(person)
.hasNickname("John");
}
Написание пользовательских классов утверждений, соответствующих объектной модели, прокладывает путь к очень читабельным тестам.
Однако, если у нас много классов, было бы сложно вручную создавать собственные классы утверждений для всех из них. Здесь в игру вступает генератор утверждений AssertJ.
Чтобы использовать генератор утверждений с Maven, нам нужно добавить плагин в файл pom.xml:
Последнюю версию assertj-assertions-generator-maven-plugin можно найти здесь.
<plugin>
<groupId>org.assertj</groupId>
<artifactId>assertj-assertions-generator-maven-plugin</artifactId>
<version>2.1.0</version>
<configuration>
<classes>
<param>com.baeldung.testing.assertj.custom.Person</param>
</classes>
</configuration>
</plugin>
Элемент классов в приведенном выше плагине помечает классы, для которых мы хотим генерировать утверждения. Пожалуйста, смотрите этот пост для других конфигураций плагина.
Генератор утверждений AssertJ создает утверждения для каждого общедоступного свойства целевого класса. Конкретное имя каждого метода утверждения зависит от типа поля или свойства. Полное описание генератора утверждений см. в этой ссылке.
Выполните следующую команду Maven в базовом каталоге проекта:
Мы должны увидеть классы утверждений, сгенерированные в папке target/generated-test-sources/assertj-assertions. Например, сгенерированный класс точки входа для сгенерированных утверждений выглядит следующим образом:
mvn assertj:generate-assertions
Теперь мы можем скопировать сгенерированные исходные файлы в тестовый каталог, а затем добавить пользовательские методы утверждений, чтобы удовлетворить наши требования к тестированию.
// generated comments are stripped off for brevity
package com.baeldung.testing.assertj.custom;
@javax.annotation.Generated(value="assertj-assertions-generator")
public class Assertions {
@org.assertj.core.util.CheckReturnValue
public static com.baeldung.testing.assertj.custom.PersonAssert
assertThat(com.baeldung.testing.assertj.custom.Person actual) {
return new com.baeldung.testing.assertj.custom.PersonAssert(actual);
}
protected Assertions() {
// empty
}
}
Важно отметить, что сгенерированный код не обязательно будет полностью правильным. На данный момент генератор не является готовым продуктом, и сообщество работает над ним.
«Следовательно, мы должны использовать генератор в качестве вспомогательного инструмента, чтобы сделать нашу жизнь проще, а не принимать его как должное.
6. Заключение
В этом руководстве мы показали, как создавать собственные утверждения для создания читаемого тестового кода с помощью библиотеки AssertJ как вручную, так и автоматически.
Если у нас есть только небольшое количество тестируемых классов, ручного решения достаточно; в противном случае следует использовать генератор.
И, как всегда, реализацию всех примеров и фрагментов кода можно найти на GitHub.
«