Test d’intégration de démarrage de printemps avec MongoDB incorporé

Test d'intégration de démarrage Spring avec Embedded MongoDB

1. Vue d'ensemble

Dans ce didacticiel, nous allons apprendre à utiliser la solution MongoDB intégrée de Flapdoodle avec Spring Boot pour exécuter les tests d'intégration MongoDB en douceur.

MongoDB is a popular NoSQL document database. Grâce à sa grande évolutivité, à son partitionnement intégré et à son excellent support communautaire, il est souvent considéré comme un «stockage NoSQLthe» par de nombreux développeurs.

Comme pour toute autre technologie de persistance,it’s critical to be able to test database integration with the rest of our application easily. Heureusement, Spring Boot nous permet d’écrire facilement ce type de test.

2. Dépendances Maven

Commençons par configurer le parent Maven pour notre projet Boot.

Merci au parentwe don’t need to define version for each Maven dependency manually.

Nous allons naturellement utiliser Spring Boot:


    org.springframework.boot
    spring-boot-starter-parent
    2.0.3.RELEASE
     

Vous pouvez trouver la dernière version de démarragehere.

Depuis que nous avons ajouté le parent Spring Boot, nous pouvons ajouter les dépendances requises sans spécifier leurs versions:


    org.springframework.boot
    spring-boot-starter-data-mongodb

spring-boot-starter-data-mongodb activera le support Spring pour MongoDB:


    de.flapdoodle.embed
    de.flapdoodle.embed.mongo
    test

de.flapdoodle.embed.mongo fournit MongoDB intégré pour les tests d'intégration.

3. Test à l'aide de MongoDB intégré

Cette section couvre deux scénarios: le test de démarrage du printemps et le test manuel.

3.1. Test de démarrage à ressort

Après avoir ajouté la dépendancede.flapdoodle.embed.mongoSpring Boot will automatically try to download and start the embedded MongoDB lors de l'exécution des tests.

Le package ne sera téléchargé qu'une fois par version, ce qui accélérera les tests suivants.

A ce stade, nous devrions pouvoir démarrer et réussir l'exemple de test d'intégration 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");
    }
}

Comme nous pouvons le constater, la base de données intégrée a été démarrée automatiquement par Spring, qui devrait également être enregistré dans la console:

...Starting MongodbExampleApplicationTests on arroyo with PID 10413...

3.2. Test de configuration manuel

Spring Boot démarrera et configurera automatiquement la base de données intégrée, puis injectera l'instanceMongoTemplate pour nous. Cependant,sometimes we might need to configure embedded Mongo database manually (par exemple, lors du test d'une version de base de données spécifique).

L'extrait suivant montre comment nous pouvons configurer manuellement l'instance MongoDB intégrée. C'est à peu près l'équivalent du test Spring précédent:

class ManualEmbeddedMongoDbIntegrationTest {
    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(new MongoClient(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");
    }
}

Notez que nous pouvons rapidement créer le beanMongoTemplate configuré pour utiliser notre base de données intégrée configurée manuellement et l'enregistrer dans le conteneur Spring en créant simplement, par exemple, une méthode@TestConfiguration avec@Bean qui retournera new MongoTemplate(new MongoClient(bindIp, port), “test”).

D'autres exemples peuvent être trouvés sur lesGitHub repository officiels de Flapdoodle.

3.3. Enregistrement

Nous pouvons configurer les messages de journalisation pour MongoDB lors de l'exécution des tests d'intégration en ajoutant ces deux propriétés au fichiersrc/test/resources/application.propertes:

logging.level.org.springframework.boot.autoconfigure.mongo.embedded
logging.level.org.mongodb

Par exemple, pour désactiver la journalisation, nous définissons simplement les valeurs suroff:

logging.level.org.springframework.boot.autoconfigure.mongo.embedded=off
logging.level.org.mongodb=off

3.4. Utiliser une vraie base de données sur la production

Depuis que nous avons ajouté la dépendancede.flapdoodle.embed.mongo en utilisant<scope>test</scope>there’s no need to disable embedded database when running on production. Tout ce que nous avons à faire est de spécifier les détails de la connexion MongoDB (par exemple, hôte et port) et nous sommes prêts à partir.

Pour utiliser un DB embarqué en dehors des tests, nous pouvons utiliser des profils Spring qui enregistreront les bonsMongoClient (embarqués ou en production) en fonction du profil actif.

Nous devrons également modifier la portée de la dépendance de production en<scope>runtime</scope>.

4. Controverse sur les tests intégrés

L'utilisation de la base de données intégrée peut sembler une bonne idée au début. En effet, c'est une bonne approche lorsque nous voulons tester si notre application se comporte correctement dans des domaines tels que:

  • Objet <→ Configuration du mappage de documents

  • Écouteurs d'événements de cycle de vie de persistance personnalisés (reportez-vous àAbstractMongoEventListener)

  • La logique de tout code travaillant directement avec la couche de persistance

Malheureusement,using an embedded server cannot be considered as “full integration testing”. MongoDB intégré à Flapdoodle n'est pas un produit MongoDB officiel. Par conséquent, nous ne pouvons pas être sûr qu'il se comporte exactement comme dans l'environnement de production.

Si nous voulons exécuter des tests de communication dans l'environnement le plus près possible de la production, une meilleure solution consiste à utiliser un conteneur d'environnement tel que Docker.

Pour en savoir plus sur Docker, lisez notre précédent articlehere.

5. Conclusion

Spring Boot simplifie considérablement l’exécution de tests qui vérifient le mappage correct des documents et l’intégration de la base de données. En ajoutant la bonne dépendance Maven, nous pouvons immédiatement utiliser les composants MongoDB dans les tests d'intégration Spring Boot.

Nous devons nous rappeler queembedded MongoDB server cannot be considered a replacement for a “real” server.

Le code source complet de tous les exemples est disponibleover on GitHub.