Статьи

Современный TDD-ориентированный тестовый шаблон Java 8 JUnit для Idea (с Mockito и AssertJ)

Настройте шаблон вашего тестового класса JUnit для Idea с BDD-подобным синтаксисом, Java 8 и дуэт Mockito-AssertJ.

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

Мой любимый фреймворк для тестирования Java (и Groovy) — Spock . Тем не менее, его макеты не подходят для каких-то целей, и я все еще использую Mockito в разных местах. Кроме того, я все еще провожу большую часть своих тренировок по тестированию в варианте JUnit / Mockito / AssertJ для команд, которые уже имеют набор тестов в этом стеке и хотели бы улучшить свои навыки, не меняя известную технологию. Поэтому в качестве промежуточной статьи в этом блоге рассказывается о тестировании в чистом стиле Java и предлагается, как настроить свою среду тестирования JUnit, предполагая, что вы уже используете Mockito и AssertJ (вы должны попробовать их в другом случае).

Этот блог состоит из частей дерева. Во-первых, я предлагаю структуру тестов на основе секций в стиле BDD, чтобы сделать ваш тест более понятным и понятным. Далее я объясню, как упростить — используя AssertJ и Mockito — конструкции с Java 8. Наконец, но не в последнюю очередь, я покажу, как настроить его в IntelliJ IDEA в качестве шаблона теста (класса) JUnit по умолчанию (который не так прост, как должно).

Часть 1. Разделы в стиле BDD

Хорошо написанные юнит-тесты должны отвечать нескольким требованиям (но это тема отдельного поста). Одним из полезных методов является четкое разделение на 3 блока кода с четко определенной ответственностью. Вы можете прочитать больше на эту тему в моем предыдущем сообщении в блоге .

В качестве повторения просто основные правила представлены в краткой форме:

  • given — инициализация тестируемого объекта + создание заглушек / насмешек, заглушка и внедрение
  • when — операция для проверки в данном тесте
  • then — полученное утверждение результата + проверка фиктивности (при необходимости)
1
2
3
4
5
6
7
8
9
@Test
public void shouldXXX() {
  //given
  ...
  //when
  ...
  //then
  ...
}

Такое разделение помогает сделать тесты короткими и сфокусированными только на одной ответственности за тестирование (в конце концов, это всего лишь модульное тестирование).

В Споке эти разделы обязательны (*) — без них тест даже не скомпилируется. В Юните есть только комментарии. Однако наличие их поощряет людей использовать их вместо того, чтобы иметь внутри один большой блок беспорядка (особенно полезно для новичков в области тестирования).

Кстати, упомянутое соглашение «когда — то» основано на (является подмножеством) гораздо более широкой концепции развития, ориентированной на поведение . Вы можете столкнуться с подобным делением на 3 кодовых блока с именемrange-act-assert, что в целом является эквивалентом.

Часть 2. Java 8 для AssertJ и Mockito

Одной из особенностей Java 8 является возможность помещать методы по умолчанию в интерфейс. Это можно использовать для упрощения вызова статических методов, что широко распространено в таких средах тестирования, как AssertJ и Mockito. Идея проста. Тестовый класс, желающий использовать данную инфраструктуру, может реализовать специальный интерфейс, чтобы «видеть» эти методы как свои собственные методы при завершении кода в IDE (вместо статических методов из внешнего класса, которые требуют присвоения имени класса до или статического импорта) , Под капотом эти стандартные методы просто делегируют выполнение статическим методам. Вы можете прочитать больше об этом в моем другом сообщении в блоге .

AssertJ изначально поддерживает эти конструкции, начиная с версии 3.0.0. Mockito 1.10 и 2.x совместимы с Java 6, и поэтому необходимо использовать сторонний проект — mockito-java8 (который должен быть интегрирован в Mockito 3 — когда он будет доступен).

Чтобы воспользоваться преимуществами завершения метода в Idea, достаточно реализовать два интерфейса:

1
2
3
4
5
6
import info.solidsoft.mockito.java8.api.WithBDDMockito;
import org.assertj.core.api.WithAssertions;
 
class SampleTest implements WithAssertions, WithBDDMockito {
 
}

Часть 3. Шаблон по умолчанию в Idea

Я большой энтузиаст вездесущей автоматизации. Разве не было бы хорошо, чтобы в ваших тестовых классах были автоматически установлены как разделы «когда», так и дополнительные интерфейсы? Давайте избавимся от этих скучных вещей из нашей жизни.

Метод испытания

Изменить метод тестирования JUnit легко. Одним из возможных способов является «CTRL-SHIFT-A -> Шаблон файла -> Код» и модификация JUnit4 Test Method для:

1
2
3
4
5
6
7
@org.junit.Test
public void should${NAME}() {
  //given
  ${BODY}
  //when
  //then
}

Чтобы добавить новый тест в существующий класс тестов, просто нажмите ALT-INSERT и выберите (или введите) JUnit4 Test Method .

Тестовый класс

Со всем тестовым классом ситуация немного сложнее. Idea предоставляет способ редактирования существующих шаблонов, однако он используется только в том случае, если тест создается с помощью CTRL-SHIFT-T из рабочего класса. Это не очень удобно с TDD, где сначала нужно создать тест. Было бы хорошо иметь новую позицию «Новый тестовый класс JUnit» рядом с «Java class», если нажата ALT-INSERT находящаяся в представлении пакета в тестовом контексте. К сожалению, для этого потребуется написать новый плагин (пример реализации для Spock). В качестве обходного пути мы можем определить обычный шаблон файла, который (в качестве ограничения) будет доступен везде (например, даже в каталоге ресурсов).

Сделайте «CTRL-SHIFT-A -> Шаблон файла -> Файлы», нажмите INSERT , назовите шаблон «JUnit with AssertJ и Mockito Test», установите расширение «java» и вставьте следующий шаблон:

1
2
3
4
5
6
7
8
9
package ${PACKAGE_NAME};
 
import info.solidsoft.mockito.java8.api.WithBDDMockito;
import org.assertj.core.api.WithAssertions;
 
#parse("File Header.java")
public class ${NAME} implements WithAssertions, WithBDDMockito {
 
}

витрина

Мы уже настроены. Давайте посмотрим, как это может выглядеть на практике (нажмите, чтобы увеличить анимацию).

Резюме

Я надеюсь, что убедил вас настроить свой тестовый шаблон, чтобы улучшить читаемость ваших тестов и сохранить несколько нажатий клавиш на тест. В этом случае, пожалуйста, потратьте 4 минуты прямо сейчас, чтобы настроить его в своей идее. В зависимости от количества написанных тестов он может начать окупаться раньше, чем вы ожидаете :).

Кстати, в начале октября я буду выступать с презентацией о новых функциях в Mockito 2 на JDD в Кракове.

Самореклама . Хотели бы вы быстро и эффективно улучшить свои навыки тестирования своей команды и знания Spock / JUnit / Mockito / AssertJ? Я провожу сжатое (единичное) обучение тестированию, которое может оказаться полезным.