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. Тествайте с помощта на Embedded 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 (напр. при тестване на конкретна версия на DB).
Следващият фрагмент показва как можем да конфигурираме ръчно вградения екземпляр на 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");
}
}
Имайте предвид, че можем бързо да създадем MongoTemplate bean, конфигуриран да използва нашата ръчно конфигурирана вградена база данни и да я регистрира в Spring контейнера, като просто създаде, например, @TestConfiguration с @Bean метод, който ще върне нов MongoTemplate(MongoClients.create(connectionString, “test”) .
Още примери можете да намерите в официалното хранилище GitHub на Flapdoodle.
3.3. Регистриране
Можем да конфигурираме регистрационни съобщения за MongoDB, когато изпълняваме тестове за интеграция, като добавим тези две свойства към src/test/resources/application.propertes файл:
logging.level.org.springframework.boot.autoconfigure.mongo.embedded
logging.level.org.mongodb
Например, за да деактивираме регистрирането, ние просто задаваме стойностите на изключено :
logging.level.org.springframework.boot.autoconfigure.mongo.embedded=off
logging.level.org.mongodb=off
3.4. Използване на реална база данни за производство
Тъй като добавихме de.flapdoodle.embed.mongo зависимост с помощта на
За да използваме вградена БД извън тестовете, можем да използваме Spring профили, които ще регистрират правилния MongoClient (вграден или производствен) в зависимост от активния профил.
Ще трябва също да променим обхвата на производствената зависимост на
4. Противоречие относно вграденото тестване
Използването на вградена база данни може да изглежда като страхотна идея в началото. Наистина, това е добър подход, когато искаме да тестваме дали нашето приложение се държи правилно в области като:
- Обект<->Конфигурация за съпоставяне на документи
- Персонализирани слушатели на събития от жизнения цикъл на постоянство (вижте AbstractMongoEventListener )
- Логиката на всеки код, работещ директно със слоя за постоянство
За съжаление, използването на вграден сървър не може да се счита за „пълно тестване за интеграция“ . Вграденият MongoDB на Flapdoodle не е официален продукт на MongoDB. Следователно не можем да сме сигурни, че се държи точно както в производствената среда.
Ако искаме да проведем комуникационни тестове в средата възможно най-близо до производството, по-доброто решение е да използваме контейнер на средата като Docker.
За да научите повече за Docker, прочетете предишната ни статия тук.