Автор оригинала: 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 .