Автор оригинала: Mike Wojtyna.
1. Обзор
В этом уроке мы узнаем, как использовать встроенное решение MongoDB Flapdoodles вместе с Spring Boot для плавного запуска интеграционных тестов MongoDB.
MongoDB-популярная база данных документов NoSQL . Благодаря высокой масштабируемости, встроенному совместному использованию и отличной поддержке сообщества многие разработчики часто считают его ” хранилищем NoSQL”.
Как и в случае с любой другой технологией сохранения, очень важно иметь возможность легко протестировать интеграцию базы данных с остальной частью нашего приложения . К счастью, Spring Boot позволяет нам легко писать такие тесты.
2. Зависимости Maven
Во-первых, давайте настроим родителя Maven для нашего загрузочного проекта.
Благодаря родительскому нам не нужно определять версию для каждой зависимости Maven вручную .
Естественно, мы будем использовать Spring Boot:
org.springframework.boot spring-boot-starter-parent 2.3.3.RELEASE
Вы можете найти последнюю версию загрузки здесь .
Поскольку мы добавили родителя Spring Boot, мы можем добавлять необходимые зависимости без указания их версий:
org.springframework.boot spring-boot-starter-data-mongodb
spring-boot-starter-data-mongodb включит поддержку Spring для MongoDB:
de.flapdoodle.embed de.flapdoodle.embed.mongo test
de.flapdoodle.embed.mongo предоставляет встроенный MongoDB для интеграционных тестов.
3. Тестирование С Использованием Встроенного MongoDB
В этом разделе рассматриваются два сценария: весенний загрузочный тест и ручной тест.
3.1. Испытание пружинной загрузки
После добавления de.flapdoodle.embed.mongo dependency Spring Boot автоматически попытается загрузить и запустить встроенный MongoDB при запуске тестов.
Пакет будет загружен только один раз для каждой версии, чтобы последующие тесты выполнялись намного быстрее.
На этом этапе мы должны быть в состоянии запустить и пройти пример интеграционного теста JUnit 5:
@DataMongoTest @ExtendWith(SpringExtension.class) public class MongoDbSpringIntegrationTest { @DisplayName("given object to save" + " when save object using MongoDB template" + " then object is saved") @Test public void test(@Autowired MongoTemplate mongoTemplate) { // given DBObject objectToSave = BasicDBObjectBuilder.start() .add("key", "value") .get(); // when mongoTemplate.save(objectToSave, "collection"); // then assertThat(mongoTemplate.findAll(DBObject.class, "collection")).extracting("key") .containsOnly("value"); } }
Как мы видим, встроенная база данных была автоматически запущена Spring, которая также должна быть зарегистрирована в консоли:
...Starting MongodbExampleApplicationTests on arroyo with PID 10413...
3.2. Ручное тестирование конфигурации
Spring Boot автоматически запустит и настроит встроенную базу данных, а затем введет для нас экземпляр MongoTemplate . Однако иногда нам может потребоваться настроить встроенную базу данных Mongo вручную (например, при тестировании конкретной версии БД).
В следующем фрагменте показано, как мы можем настроить встроенный экземпляр MongoDB вручную. Это примерно эквивалентно предыдущему весеннему тесту:
class ManualEmbeddedMongoDbIntegrationTest { private static final String CONNECTION_STRING = "mongodb://%s:%d"; private MongodExecutable mongodExecutable; private MongoTemplate mongoTemplate; @AfterEach void clean() { mongodExecutable.stop(); } @BeforeEach void setup() throws Exception { String ip = "localhost"; int port = 27017; IMongodConfig mongodConfig = new MongodConfigBuilder().version(Version.Main.PRODUCTION) .net(new Net(ip, port, Network.localhostIsIPv6())) .build(); MongodStarter starter = MongodStarter.getDefaultInstance(); mongodExecutable = starter.prepare(mongodConfig); mongodExecutable.start(); mongoTemplate = new MongoTemplate(MongoClients.create(String.format(CONNECTION_STRING, ip, port)), "test"); } @DisplayName("given object to save" + " when save object using MongoDB template" + " then object is saved") @Test void test() throws Exception { // given DBObject objectToSave = BasicDBObjectBuilder.start() .add("key", "value") .get(); // when mongoTemplate.save(objectToSave, "collection"); // then assertThat(mongoTemplate.findAll(DBObject.class, "collection")).extracting("key") .containsOnly("value"); } }
Обратите внимание, что мы можем быстро создать MongoTemplate bean, настроенный для использования нашей встроенной базы данных, настроенной вручную, и зарегистрировать ее в контейнере Spring, просто создав, например, @TestConfiguration с @Bean методом, который вернет new MongoTemplate(MongoClients.create(ConnectionString, “test”) .
Дополнительные примеры можно найти на официальном репозитории Flapdoodles GitHub|/.
3.3. Ведение журнала
Мы можем настроить сообщения журнала для MongoDB при выполнении интеграционных тестов, добавив эти два свойства в файл src/test/resources/application.propertes :
logging.level.org.springframework.boot.autoconfigure.mongo.embedded logging.level.org.mongodb
Например, чтобы отключить ведение журнала, мы просто устанавливаем значения в off :
logging.level.org.springframework.boot.autoconfigure.mongo.embedded=off logging.level.org.mongodb=off
3.4. Использование Реальной базы данных о производстве
Поскольку мы добавили de.flapdoodle.embed.mongo зависимость с помощью test | нет необходимости отключать встроенную базу данных при запуске в рабочей среде . Все, что нам нужно сделать, это указать детали подключения MongoDB (например, хост и порт), и мы готовы к работе.
Чтобы использовать встроенную БД вне тестов, мы можем использовать профили Spring, которые будут регистрировать правильный MongoClient (встроенный или производственный) в зависимости от активного профиля.
Нам также нужно будет изменить область производственной зависимости на runtime .
4. Споры по Встроенному Тестированию
Использование встроенной базы данных может показаться отличной идеей в самом начале. Действительно, это хороший подход, когда мы хотим проверить, правильно ли наше приложение ведет себя в таких областях, как:
- Объект<->Конфигурация сопоставления документов
- Пользовательские прослушиватели событий жизненного цикла сохранения (см. AbstractMongoEventListener )
- Логика любого кода, работающего непосредственно со слоем персистентности
К сожалению, использование встроенного сервера не может рассматриваться как “полное интеграционное тестирование” . Flapdoodles embedded MongoDB не является официальным продуктом MongoDB. Поэтому мы не можем быть уверены, что он ведет себя точно так же, как в производственной среде.
Если мы хотим запустить тесты связи в среде, максимально приближенной к рабочей, лучшим решением является использование контейнера среды, такого как Docker.
Чтобы узнать больше о Докере, прочитайте нашу предыдущую статью здесь .
5. Заключение
Spring Boot чрезвычайно упрощает выполнение тестов, которые проверяют правильное сопоставление документов и интеграцию с базой данных. Добавив правильную зависимость Maven, мы сразу же сможем использовать компоненты MongoDB в интеграционных тестах Spring Boot.
Мы должны помнить, что встроенный сервер MongoDB не может считаться заменой “реальному” серверу .
Полный исходный код всех примеров доступен на GitHub .