web-dev-qa-db-fra.com

MongoDB intégré lors de l'exécution de tests d'intégration

Ma question est une variante de celle-ci .

Étant donné que mon Java projet Web-app nécessite beaucoup de filtres/requêtes en lecture et d'interfaces avec des outils tels que GridFS, j'ai du mal à trouver un moyen judicieux d'utiliser MongoDB de la même manière que la solution ci-dessus. suggère.

Par conséquent, j’envisage d’exécuter une instance intégrée de MongoDB parallèlement à mes tests d’intégration. Je voudrais que démarre automatiquement (soit pour chaque test, soit pour la suite entière), vider la base de données pour chaque test, et arrêté à la fin. Ces tests peuvent être exécutés sur des machines de développement ainsi que sur le serveur CI. Par conséquent, ma solution devra également être portable .

Toute personne mieux informée sur MongoDB peut-elle m'aider à se faire une idée de la faisabilité de cette approche et/ou peut-être suggérer des lectures qui pourraient m'aider à démarrer?

Je suis également ouvert à d'autres suggestions que les gens pourraient avoir sur la façon dont je pourrais aborder ce problème ...

107
seanhodges

Voici une version mise à jour (pour 2019) de réponse acceptée de @rozky (beaucoup de choses ont été modifiées dans les bibliothèques Mongo et Embedded MongoDB).

package com.example.mongo;

import com.mongodb.BasicDBObject;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import de.flapdoodle.embed.mongo.MongodExecutable;
import de.flapdoodle.embed.mongo.MongodProcess;
import de.flapdoodle.embed.mongo.MongodStarter;
import de.flapdoodle.embed.mongo.config.IMongodConfig;
import de.flapdoodle.embed.mongo.config.MongodConfigBuilder;
import de.flapdoodle.embed.mongo.config.Net;
import de.flapdoodle.embed.mongo.distribution.Version;
import de.flapdoodle.embed.process.runtime.Network;
import Java.util.Date;
import org.junit.After;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;

public class EmbeddedMongoTest
{
    private static final String DATABASE_NAME = "embedded";

    private MongodExecutable mongodExe;
    private MongodProcess mongod;
    private MongoClient mongo;

    @Before
    public void beforeEach() throws Exception {
        MongodStarter starter = MongodStarter.getDefaultInstance();
        String bindIp = "localhost";
        int port = 12345;
        IMongodConfig mongodConfig = new MongodConfigBuilder()
        .version(Version.Main.PRODUCTION)
        .net(new Net(bindIp, port, Network.localhostIsIPv6()))
        .build();
        this.mongodExe = starter.prepare(mongodConfig);
        this.mongod = mongodExe.start();
        this.mongo = new MongoClient(bindIp, port);
    }

    @After
    public void afterEach() throws Exception {
        if (this.mongod != null) {
            this.mongod.stop();
            this.mongodExe.stop();
        }
    }

    @Test
    public void shouldCreateNewObjectInEmbeddedMongoDb() {
        // given
        MongoDatabase db = mongo.getDatabase(DATABASE_NAME);
        db.createCollection("testCollection");
        MongoCollection<BasicDBObject> col = db.getCollection("testCollection", BasicDBObject.class);

        // when
        col.insertOne(new BasicDBObject("testDoc", new Date()));

        // then
        assertEquals(1L, col.countDocuments());
    }

}
5
Collin Krawll

J'ai trouvé la bibliothèque Embedded MongoDB qui semble assez prometteuse et fait ce que vous avez demandé.

Supporte actuellement les versions de MongoDB: 1.6.5 à 3.1.6, à condition que les fichiers binaires soient toujours disponibles à partir du miroir configuré.

Voici un exemple d'utilisation que je viens d'essayer et qui fonctionne parfaitement:

public class EmbeddedMongoTest {
    private static final String DATABASE_NAME = "embedded";

    private MongodExecutable mongodExe;
    private MongodProcess mongod;
    private Mongo mongo;

    @Before
    public void beforeEach() throws Exception {
        MongoDBRuntime runtime = MongoDBRuntime.getDefaultInstance();
        mongodExe = runtime.prepare(new MongodConfig(Version.V2_3_0, 12345, Network.localhostIsIPv6()));
        mongod = mongodExe.start();
        mongo = new Mongo("localhost", 12345);
    }

    @After
    public void afterEach() throws Exception {
        if (this.mongod != null) {
            this.mongod.stop();
            this.mongodExe.stop();
        }
    }

    @Test
    public void shouldCreateNewObjectInEmbeddedMongoDb() {
        // given
        DB db = mongo.getDB(DATABASE_NAME);
        DBCollection col = db.createCollection("testCollection", new BasicDBObject());

        // when
        col.save(new BasicDBObject("testDoc", new Date()));

        // then
        assertThat(col.getCount(), Matchers.is(1L));
    }
}
94
rozky

Il existe un produit Foursquare Fongo . Fongo est une implémentation en mémoire Java de mongo. Il intercepte les appels au pilote standard mongo-Java pour les recherches, les mises à jour, les insertions, les suppressions et d'autres méthodes. Son utilisation principale est une unité légère. tester où vous ne voulez pas lancer un processus mongo.

18
zlob

Si vous utilisez Maven, vous pouvez être intéressé par un plugin que j'ai créé et qui enveloppe l'API API intégrée de mongo de flapdoodle.de :

embedmongo-maven-plugin

Il fournit un objectif start que vous pouvez utiliser pour démarrer n’importe quelle version de MongoDB de votre choix (par exemple, pendant pre-integration-test) et un objectif stop qui arrêtera MongoDB (par exemple, pendant post-integration-test).

L'avantage réel de l'utilisation de ce plugin par rapport aux autres est qu'il n'est pas nécessaire d'installer MongoDB au préalable. Les binaires MongoDB sont téléchargés et stockés dans ~/.embedmongo pour les futures constructions.

7
joelittlejohn

Si vous utilisez sbt et specs2, j’ai écrit le même genre d’emballage pour embedmongo

https://github.com/athieriot/specs2-embedmongo

7
Aurélien Thieriot

avec spring-boot 1.3, vous pouvez utiliser EmbeddedMongoAutoConfiguration

pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.2.RELEASE</version>
</parent>
 ...
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    <dependency>
        <groupId>de.flapdoodle.embed</groupId>
        <artifactId>de.flapdoodle.embed.mongo</artifactId>
        <version>${embedded-mongo.version}</version>
    </dependency>

MongoConfig

@Configuration
@EnableAutoConfiguration(exclude = { EmbeddedMongoAutoConfiguration.class })
public class MongoConfig{
}
4
panser

Vous pouvez exécuter MongoDB en mémoire à partir de la version 3.2.6. De la site :

À partir de MongoDB Enterprise version 3.2.6, le moteur de stockage en mémoire fait partie de la disponibilité générale (GA) dans les versions 64 bits. Hormis certaines métadonnées et données de diagnostic, le moteur de stockage en mémoire ne conserve aucune donnée sur le disque, y compris les données de configuration, les index, les informations d'identification de l'utilisateur, etc.

3
Irwin

Vous pouvez également vérifier ce projet qui simule une MongoDB dans la mémoire de la machine virtuelle Java. https://github.com/thiloplanz/jmockmongo Mais il est encore en développement.

2
Sebastien Lorber

Si vous utilisez Maven, vous pouvez utiliser le notre http://mvnrepository.com/artifact/com.wenzani/mongodb-maven-plugin

2
markdsievers

Pas seulement pour les tests unitaires, mais lisez ce billet de blog si vous souhaitez exécuter MongoDB (même un cluster) en tant que déploiement en mémoire si vous utilisez Linux.

http://edgystuff.tumblr.com/post/49304254688

Ce serait bien de l'avoir en dehors de la boîte comme RavenDB cependant.

2
Tamir

Semblable à l'embedmongo-maven-plugin mentionné ici, il existe également un Gradle Mongo Plugin disponible.

Comme le plugin Maven, il enveloppe également = flapdoodle EmbeddedMongoDb api et vous permet d'exécuter une instance gérée de Mongo à partir de vos versions de Gradle.

1
Robert Taylor

Vérifiez cet exemple de code ici: https://github.com/familysyan/embedded-mongo-integ . Pas d'installation, pas de dépendance. Il s'agit simplement d'un script ant indépendant de la plate-forme qui télécharge et configure pour vous. Il nettoie également tout après vos tests.

0
Edmond