Почти у всех приложений есть одно общее требование, они должны отправить электронное письмо с уведомлением о чем-либо зарегистрированному пользователю. Это может быть счет, подтверждение действия или восстановление пароля. Тестирование этого варианта использования может быть затруднительным, использование блочных и заглушек подходит для модульных тестов, но с использованием компонентного теста, который тестирует весь стек.
В этом посте я собираюсь показать вам, как Docker и MailHog могут помочь вам в тестировании этой части кода.
MailHog — супер простой SMTP-сервер для инструмента тестирования электронной почты для разработчиков:
- Настройте приложение для использования MailHog для доставки SMTP
- Просматривайте сообщения в веб-интерфейсе или извлекайте их с помощью JSON API
- При желании отправлять сообщения на реальные SMTP-серверы для доставки
- Образ Docker с установленным MailHog
Обратите внимание, что, поскольку вы можете получить любое сообщение, отправленное на почтовый сервер с помощью JSON API, очень просто проверить, действительно ли сообщение доставлено, и, конечно, утверждать его в любом из полей сообщения.
Arquillian Cube — это расширение Arquillian, которое можно использовать для управления контейнерами Docker в ваших тестах. Чтобы использовать его, вам нужен демон Docker , работающий на компьютере (он может быть локальным или нет), но, вероятно, он будет локальным.
Arquillian Cube предлагает три различных способа определения контейнера (ов):
- Определение файла docker-compose.
- Определение объекта-контейнера.
- Использование контейнерного объекта DSL.
В этом примере я собираюсь показать вам подход «Контейнерный объект DSL», но любой другой работает также.
Чтобы использовать DSL объекта-контейнера, вам просто нужно создать экземпляр ContainerDslRule (если вы используете правила JUnit) или использовать бегунок Arquillian в случае использования JUnit, TestNG или Spock. Вы можете прочитать больше о Контейнерном объекте DSL на http://arquillian.org/arquillian-cube/#_arquillian_cube_and_container_object_dsl
В качестве примера определения контейнера Redis:
|
1
2
3
4
5
6
|
@ClassRulepublic static ContainerDslRule redis = new ContainerDslRule("redis:3.2.6") .withPortBinding(6379);Jedis jedis = new Jedis(redis.getIpAddress(), redis.getBindPort(6379));jedis.set("foo", "bar"); |
При запуске этого теста запускается образ Redis Docker, выполняются тесты и, наконец, экземпляр Docker останавливается.
Итак, давайте посмотрим, как сделать то же самое, но вместо Redis, используя образ Mailhog Docker .
Важно отметить, что ContainerDslRule — это универсальный класс, который можно расширить, чтобы он стал более конкретным для конкретного варианта использования. И это то, что мы собираемся сделать для
Mailhog .
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public class MailhogContainer extends ContainerDslRule { protected MailhogContainer(String image) { super(image); } public static MailhogContainer createDefaultMailhogContainer() { MailhogContainer mailhogContainer = new MailhogContainer("mailhog/mailhog:v1.0.0"); mailhogContainer.withPortBinding(1025, 8025); return mailhogContainer; } public void should_receive_email_with_subject(String subject) { final ArrayList<String> expected = new ArrayList<>(); expected.add(subject); RestAssured.given() .when() .then() .assertThat() .body("Content.Headers.Subject", CoreMatchers.hasItems(expected)); }} |
Прежде всего нам нужно создать класс, расширяющийся от
ContainerDslRule , так что все по-прежнему является правилом JUnit, но настроенным. Затем мы создаем фабричный метод, который создает
Объект MailhogContainer , настройка имени изображения и привязки портов. Наконец, метод подтверждения используется для подключения к Rest API сервера Mailhog, чтобы проверить, есть ли какое-либо сообщение с данной темой.
Затем мы можем написать тест, используя это новое правило.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public class MailServiceTest { @ClassRule public static MailhogContainer mailhog = MailhogContainer.createDefaultMailhogContainer(); @Test public void should_send_an_email() throws Exception { // given final MailService mailService = new MailService( mailhog.getIpAddress(), mailhog.getBindPort(1025)); // when mailService.send("lollypop", "lolly.pop@mymail.com", "Invoice: 1234", "Thank you very much for buying this product. Here's your invoice"); // then mailhog.should_receive_email_with_subject("Invoice: 1234"); }} |
Этот тест просто настраивает класс MailService с конфигурацией контейнера Docker , он отправляет электронное письмо и, наконец, делегирует объекту контейнера, чтобы проверить, было ли получено письмо или нет.
Обратите внимание, что помещение всего в объект делает этот объект многократно используемым в других тестах и даже в других проектах. Вы можете создать независимый проект со всеми вашими индивидуально разработанными объектами-контейнерами и просто повторно использовать их, импортируя их в качестве тестового файла в размещенный проект.
Код: https://github.com/lordofthejars/mailtest
| Опубликовано на Java Code Geeks с разрешения Алекса Сото, партнера нашей программы JCG . Смотрите оригинальную статью здесь: Тестирование кода, который требует почтовый сервер
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |