1. Přehled
V tomto tutoriálu se naučíme, jak používat vestavěné řešení MongoDB od Flapdoodle spolu se Spring Boot k hladkému spouštění testů integrace MongoDB.
MongoDB je oblíbená databáze dokumentů NoSQL . Díky vysoké škálovatelnosti, vestavěnému sdílení a skvělé podpoře komunity je často považován za „the úložiště NoSQL“ od mnoha vývojářů.
Stejně jako u jakékoli jiné technologie persistence je důležité, aby bylo možné snadno otestovat integraci databáze se zbytkem naší aplikace . Naštěstí nám Spring Boot umožňuje snadno psát tento druh testů.
2. Maven Dependencies
Nejprve nastavíme nadřazený prvek Maven pro náš projekt Boot.
Díky nadřazenému nemusíme ručně definovat verzi pro každou závislost Maven .
Samozřejmě budeme používat 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>
Nejnovější verzi bootování naleznete zde.
Protože jsme přidali rodiče Spring Boot, můžeme přidat požadované závislosti, aniž bychom uváděli jejich verze:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
spring-boot-starter-data-mongodb povolí podporu Spring pro MongoDB:
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
de.flapdoodle.embed.mongo poskytuje vestavěný MongoDB pro integrační testy.
3. Test pomocí Embedded MongoDB
Tato část pokrývá dva scénáře:test Spring Boot a ruční test.
3.1. Spring Boot Test
Po přidání de.flapdoodle.embed.mongo závislost Spring Boot se automaticky pokusí stáhnout a spustit vložený MongoDB při provádění testů.
Balíček bude stažen pouze jednou pro každou verzi, takže následné testy probíhají mnohem rychleji.
V této fázi bychom měli být schopni spustit a projít ukázkovým integračním testem 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 vidíme, vestavěná databáze byla automaticky spuštěna Springem, který by měl být také přihlášen do konzole:
...Starting MongodbExampleApplicationTests on arroyo with PID 10413...
3.2. Test ruční konfigurace
Spring Boot automaticky spustí a nakonfiguruje vestavěnou databázi a poté vloží MongoTemplate například pro nás. Někdy však může být nutné nakonfigurovat vestavěnou databázi Mongo ručně (např. při testování konkrétní verze DB).
Následující úryvek ukazuje, jak můžeme nakonfigurovat vestavěnou instanci MongoDB ručně. Toto je zhruba ekvivalent předchozího jarního testu:
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");
}
}
Všimněte si, že můžeme rychle vytvořit MongoTemplate bean nakonfigurovaný tak, aby používal naši ručně nakonfigurovanou vestavěnou databázi a registroval ji v kontejneru Spring pouhým vytvořením, např. @TestConfiguration s @Bean metoda, která vrátí new MongoTemplate(MongoClients.create(connectionString, “test”) .
Další příklady lze nalézt v oficiálním úložišti GitHub Flapdoodle.
3.3. Logování
Můžeme nakonfigurovat protokolovací zprávy pro MongoDB při spouštění integračních testů přidáním těchto dvou vlastností do src/test/resources/application.propertes soubor:
logging.level.org.springframework.boot.autoconfigure.mongo.embedded
logging.level.org.mongodb
Chcete-li například zakázat protokolování, jednoduše nastavíme hodnoty na off :
logging.level.org.springframework.boot.autoconfigure.mongo.embedded=off
logging.level.org.mongodb=off
3.4. Použití skutečné databáze na produkci
Protože jsme přidali de.flapdoodle.embed.mongo závislost pomocí
Pro použití embedded DB mimo testy můžeme použít profily Spring, které zaregistrují správného MongoClienta (vestavěné nebo produkční) v závislosti na aktivním profilu.
Budeme také muset změnit rozsah produkční závislosti na
4. Kontroverze vestavěného testování
Použití vestavěné databáze může na začátku vypadat jako skvělý nápad. Ve skutečnosti je to dobrý přístup, když chceme otestovat, zda se naše aplikace chová správně v oblastech, jako jsou:
- Objekt<->Konfigurace mapování dokumentu
- Vlastní posluchače událostí životního cyklu trvalosti (viz AbstractMongoEventListener )
- Logika jakéhokoli kódu pracujícího přímo s vrstvou persistence
Bohužel používání vestavěného serveru nelze považovat za „testování plné integrace“ . Vložený MongoDB Flapdoodle není oficiální produkt MongoDB. Proto si nemůžeme být jisti, že se chová přesně jako v produkčním prostředí.
Pokud chceme spouštět komunikační testy v prostředí co nejblíže produkci, je lepším řešením použít kontejner prostředí, jako je Docker.
Chcete-li se o Dockeru dozvědět více, přečtěte si náš předchozí článek zde.