Рубрики
Без рубрики

Тестирование интеграции Spring Boot со встроенным MongoDB

Узнайте, как использовать встроенное решение MongoDB Flapdoodles вместе с Spring Boot для плавного запуска интеграционных тестов MongoDB.

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