1. Przegląd
W tym samouczku dowiemy się, jak używać wbudowanego rozwiązania MongoDB Flapdoodle razem z Spring Boot, aby płynnie uruchamiać testy integracji MongoDB.
MongoDB to popularna baza danych dokumentów NoSQL . Dzięki wysokiej skalowalności, wbudowanemu shardingowi i doskonałemu wsparciu społeczności jest często uważany za „the NoSQL” przez wielu programistów.
Podobnie jak w przypadku każdej innej technologii trwałości, istotna jest możliwość łatwego testowania integracji bazy danych z resztą naszej aplikacji . Na szczęście Spring Boot pozwala nam łatwo pisać tego rodzaju testy.
2. Zależności Mavena
Najpierw skonfigurujmy rodzica Maven dla naszego projektu Boot.
Dzięki nadrzędnemu nie musimy ręcznie definiować wersji dla każdej zależności Maven .
Naturalnie będziemy używać 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>
Najnowszą wersję Boot można znaleźć tutaj.
Ponieważ dodaliśmy rodzica Spring Boot, możemy dodać wymagane zależności bez określania ich wersji:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
wiosenny-boot-starter-data-mongodb włączy obsługę Spring dla MongoDB:
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
de.flapdoodle.embed.mongo zapewnia wbudowaną bazę danych MongoDB do testów integracyjnych.
3. Testuj za pomocą osadzonej bazy danych MongoDB
Ta sekcja obejmuje dwa scenariusze:test Spring Boot i test ręczny.
3.1. Test rozruchu sprężynowego
Po dodaniu de.flapdoodle.embed.mongo zależność Spring Boot automatycznie spróbuje pobrać i uruchomić osadzoną MongoDB podczas przeprowadzania testów.
Pakiet zostanie pobrany tylko raz dla każdej wersji, dzięki czemu kolejne testy będą przebiegać znacznie szybciej.
Na tym etapie powinniśmy być w stanie rozpocząć i zdać przykładowy test integracyjny 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");
}
}
Jak widać, wbudowana baza danych została automatycznie uruchomiona przez Spring, co również powinno być rejestrowane w konsoli:
...Starting MongodbExampleApplicationTests on arroyo with PID 10413...
3.2. Ręczny test konfiguracji
Spring Boot automatycznie uruchomi i skonfiguruje wbudowaną bazę danych, a następnie wstrzyknie MongoTemplate przykład dla nas. Jednak czasami może być konieczne ręczne skonfigurowanie wbudowanej bazy danych Mongo (np. podczas testowania określonej wersji bazy danych).
Poniższy fragment pokazuje, jak ręcznie skonfigurować osadzoną instancję MongoDB. Jest to mniej więcej odpowiednik poprzedniego testu wiosennego:
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");
}
}
Pamiętaj, że możemy szybko utworzyć MongoTemplate bean skonfigurowany do korzystania z naszej ręcznie skonfigurowanej wbudowanej bazy danych i rejestrowania jej w kontenerze Spring, po prostu tworząc np. @TestConfiguration z @Bean metoda, która zwróci nowy MongoTemplate(MongoClients.create(connectionString, „test”) .
Więcej przykładów można znaleźć w oficjalnym repozytorium GitHub Flapdoodle.
3.3. Logowanie
Możemy skonfigurować komunikaty rejestrowania dla MongoDB podczas uruchamiania testów integracji, dodając te dwie właściwości do src/test/resources/application.propertes plik:
logging.level.org.springframework.boot.autoconfigure.mongo.embedded
logging.level.org.mongodb
Na przykład, aby wyłączyć rejestrowanie, po prostu ustawiamy wartości na off :
logging.level.org.springframework.boot.autoconfigure.mongo.embedded=off
logging.level.org.mongodb=off
3.4. Korzystanie z prawdziwej bazy danych w produkcji
Ponieważ dodaliśmy de.flapdoodle.embed.mongo zależność przy użyciu
Aby użyć osadzonej bazy danych poza testami, możemy użyć profili Spring, które zarejestrują właściwego MongoClient (osadzone lub produkcja) w zależności od aktywnego profilu.
Musimy również zmienić zakres zależności produkcyjnej na
4. Kontrowersje dotyczące testów wbudowanych
Korzystanie z wbudowanej bazy danych może na początku wyglądać na świetny pomysł. Rzeczywiście, jest to dobre podejście, gdy chcemy sprawdzić, czy nasza aplikacja zachowuje się poprawnie w obszarach takich jak:
- Obiekt<->Konfiguracja mapowania dokumentów
- Niestandardowe detektory zdarzeń cyklu życia trwałości (patrz AbstractMongoEventListener )
- Logika dowolnego kodu działającego bezpośrednio z warstwą trwałości
Niestety korzystanie z wbudowanego serwera nie może być uważane za „pełne testowanie integracji” . MongoDB wbudowane w Flapdoodle nie jest oficjalnym produktem MongoDB. Dlatego nie możemy być pewni, że zachowuje się dokładnie tak, jak w środowisku produkcyjnym.
Jeśli chcemy uruchomić testy komunikacji w środowisku jak najbliżej produkcyjnym, lepszym rozwiązaniem jest użycie kontenera środowiska, takiego jak Docker.
Aby dowiedzieć się więcej o platformie Docker, przeczytaj nasz poprzedni artykuł tutaj.