MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Test d'intégration Spring Boot avec MongoDB intégré

1. Présentation

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

MongoDB est une base de données de documents NoSQL populaire . Grâce à sa haute évolutivité, au sharding intégré et à l'excellent support de la communauté, il est souvent considéré comme "le Stockage NoSQL" par de nombreux développeurs.

Comme pour toute autre technologie de persistance, il est essentiel de pouvoir tester facilement l'intégration de la base de données avec le reste de notre application . Heureusement, Spring Boot nous permet d'écrire facilement ce type de tests.

2. Dépendances Maven

Tout d'abord, configurons le parent Maven pour notre projet Boot.

Grâce au parent nous n'avons pas besoin de définir manuellement la version pour chaque dépendance Maven .

Nous allons naturellement utiliser 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>

Vous pouvez trouver la dernière version de Boot ici.

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

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

spring-boot-starter-data-mongodb activera la prise en charge de Spring pour MongoDB :

<dependency>
    <groupId>de.flapdoodle.embed</groupId>
    <artifactId>de.flapdoodle.embed.mongo</artifactId>
    <scope>test</scope>
</dependency>

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

3. Tester avec MongoDB intégré

Cette section couvre deux scénarios :le test Spring Boot et le test manuel.

3.1. Test de démarrage du printemps

Après avoir ajouté de.flapdoodle.embed.mongo dependency Spring Boot essaiera automatiquement de télécharger et de démarrer le MongoDB intégré lors de l'exécution de tests.

Le package ne sera téléchargé qu'une seule fois pour chaque version afin que les tests suivants s'exécutent beaucoup plus rapidement.

À ce stade, nous devrions être en mesure de démarrer et de 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 voir, la base de données embarquée a été automatiquement lancée par Spring, qui devrait également être connecté dans la console :

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

3.2. Test de configuration manuelle

Spring Boot démarrera et configurera automatiquement la base de données intégrée, puis injectera MongoTemplate exemple pour nous. Cependant, parfois, nous devrons peut-être configurer manuellement la base de données Mongo intégrée (par exemple, lors du test d'une version de base de données spécifique).

L'extrait de code 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 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");
    }
}

Notez que nous pouvons créer rapidement MongoTemplate bean 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, un @TestConfiguration avec @Bean méthode qui renverra new MongoTemplate(MongoClients.create(connectionString, "test") .

Plus d'exemples peuvent être trouvés sur le dépôt GitHub officiel de Flapdoodle.

3.3. Journalisation

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 à src/test/resources/application.propertes fichier :

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 sur off :

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

3.4. Utilisation d'une véritable base de données en production

Depuis que nous avons ajouté de.flapdoodle.embed.mongo dépendance à l'aide de test il n'est pas nécessaire de désactiver la base de données intégrée lors de l'exécution en production . Tout ce que nous avons à faire est de spécifier les détails de la connexion MongoDB (par exemple, l'hôte et le port) et nous sommes prêts à partir.

Pour utiliser une base de données intégrée en dehors des tests, nous pouvons utiliser des profils Spring qui enregistreront le bon MongoClient (embarqué ou production) selon le profil actif.

Nous devrons également modifier la portée de la dépendance de production en exécution .

4. Controverse sur les tests intégrés

L'utilisation d'une base de données intégrée peut sembler une excellente 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 (voir AbstractMongoEventListener )
  • La logique de tout code fonctionnant directement avec la couche de persistance

Malheureusement, l'utilisation d'un serveur intégré ne peut pas être considérée comme un "test d'intégration complet" . Le MongoDB intégré de Flapdoodle n'est pas un produit MongoDB officiel. Par conséquent, nous ne pouvons pas être sûrs 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 article précédent ici.