1. Обзор
В этом руководстве мы узнаем, как использовать встроенное решение MongoDB от Flapdoodle вместе с Spring Boot для плавного запуска интеграционных тестов MongoDB.
MongoDB — популярная база данных документов NoSQL . Благодаря высокой масштабируемости, встроенному сегментированию и отличной поддержке сообщества многие разработчики часто называют его «хранилищем NoSQL» .
Как и в случае с любой другой технологией персистентности, очень важно иметь возможность легко протестировать интеграцию базы данных с остальной частью нашего приложения . К счастью, Spring Boot позволяет нам легко писать такие тесты.
2. Зависимости Maven
Во-первых, давайте настроим родительский Maven для нашего проекта Boot.
Благодаря родителю нам не нужно вручную определять версию для каждой зависимости Maven .
Естественно, мы будем использовать Spring Boot:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.1</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
Вы можете найти последнюю версию Boot здесь .
Поскольку мы добавили родителя Spring Boot, мы можем добавить необходимые зависимости, не указывая их версии:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
spring-boot-starter-data-mongodb
включит поддержку Spring для MongoDB:
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
de.flapdoodle.embed.mongo
предоставляет встроенную базу данных MongoDB для интеграционных тестов.
3. Протестируйте с помощью встроенной MongoDB
В этом разделе рассматриваются два сценария: тест Spring Boot и ручной тест.
3.1. Весенний загрузочный тест
После добавления зависимости de.flapdoodle.embed.mongo
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 вручную. Это примерно эквивалентно предыдущему тесту Spring:
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;
ImmutableMongodConfig mongodConfig = MongodConfig
.builder()
.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");
}
}
Обратите внимание, что мы можем быстро создать bean-компонент MongoTemplate
, сконфигурированный для использования нашей настроенной вручную встроенной базы данных, и зарегистрировать его в контейнере Spring, просто создав, например, @TestConfiguration
с методом @Bean
, который вернет новый MongoTemplate(MongoClients.create(connectionString, " испытание»)
.
Больше примеров можно найти в официальном репозитории Flapdoodle на 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 с помощью
<scope>test</scope>
, нет необходимости отключать встроенную базу данных при работе в рабочей среде . Все, что нам нужно сделать, это указать детали подключения к MongoDB (например, хост и порт), и все готово.
Чтобы использовать встроенную БД вне тестов, мы можем использовать профили Spring, которые будут регистрировать правильный MongoClient
(встроенный или рабочий) в зависимости от активного профиля.
Нам также нужно изменить область действия производственной зависимости на <scope>runtime</scope>
.
4. Споры о встроенном тестировании
Поначалу использование встроенной базы данных может показаться отличной идеей. Действительно, это хороший подход, когда мы хотим проверить, правильно ли ведет себя наше приложение в таких областях, как:
- Конфигурация сопоставления объекта<->документа
- Пользовательские прослушиватели событий жизненного цикла сохраняемости (см
. AbstractMongoEventListener
) - Логика любого кода, работающего напрямую с персистентным слоем
К сожалению, использование встроенного сервера нельзя рассматривать как «полное интеграционное тестирование» . Встроенная MongoDB от Flapdoodle не является официальным продуктом MongoDB. Поэтому мы не можем быть уверены, что он ведет себя именно так, как в производственной среде.
Если мы хотим запускать коммуникационные тесты в среде, максимально приближенной к рабочей, лучшим решением будет использование контейнера среды, такого как Docker.
Чтобы узнать больше о Docker, прочитайте нашу предыдущую статью здесь .
5. Вывод
Spring Boot чрезвычайно упрощает запуск тестов, проверяющих правильность сопоставления документов и интеграции с базой данных. Добавив правильную зависимость Maven, мы сразу же можем использовать компоненты MongoDB в интеграционных тестах Spring Boot.
Нужно помнить, что встроенный сервер MongoDB нельзя считать заменой «настоящему» серверу .
Полный исходный код всех примеров доступен на GitHub .