Встроенный MongoDB при запуске интеграционных тестов - PullRequest
108 голосов
/ 22 июня 2011

Мой вопрос - это вариант этого .

Поскольку мой проект веб-приложения на Java требует большого количества фильтров / запросов чтения и интерфейсов с такими инструментами, как GridFS, я изо всех силподумать о разумном способе использования MongoDB так, как предлагает приведенное выше решение.

Поэтому я рассматриваю возможность запуска встроенного экземпляра MongoDB вместе с моими интеграционными тестами.Я бы хотел, чтобы запускался автоматически (для каждого теста или для всего набора), сбрасывал базу данных для каждого теста и выключался вконец.Эти тесты могут выполняться на машинах разработки, а также на сервере CI, поэтому мое решение также должно быть переносным .

Может ли кто-нибудь, кто имеет больше знаний о MongoDB, помочь мне понятьвыполнимость этого подхода и / или, возможно, предложить какие-либо материалы для чтения, которые могли бы помочь мне начать?

Я также открыт для других предложений, которые могут возникнуть у людей о том, как я могу подойти к этой проблеме ...

Ответы [ 13 ]

94 голосов
/ 23 марта 2012

Я нашел Embedded MongoDB библиотека, которая выглядит довольно многообещающе и выполняет то, что вы просили.

В настоящее время поддерживает версии MongoDB: 1.6.5 до 3.1.6, при условии, что двоичные файлы все еще доступны из настроенного зеркала.

Вот краткий пример использования, который я только что попробовал, и он отлично работает:

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));
    }
}
18 голосов
/ 02 октября 2013

Есть продукт Foursquare Фонго .Фонго - это Java-реализация Монго в памяти.Он перехватывает вызовы стандартного драйвера mongo-java для поиска, обновления, вставки, удаления и других методов.Основное применение - для облегченного модульного тестирования, когда вы не хотите ускорять процесс монго.

7 голосов
/ 28 июня 2012

Если вы используете sbt и specs2, я написал такую ​​же оболочку для embedmongo

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

7 голосов
/ 24 июня 2012

Если вы используете Maven, возможно, вас заинтересует созданный мной плагин, который обернет API flapdoodle.de 'embedded mongo' :

embedmongo-maven-plugin

Обеспечивает цель start, которую можно использовать для запуска любой версии MongoDB, которую вы хотите (например, во время pre-integration-test), и цель stop, которая останавливает MongoDB (например,в течение post-integration-test).

Реальное преимущество использования этого плагина перед другими заключается в том, что нет необходимости предварительно устанавливать MongoDB.Двоичные файлы MongoDB загружаются и сохраняются в ~/.embedmongo для будущих сборок.

5 голосов
/ 17 января 2019

Вот обновленная (для 2019 г.) версия принятого ответа от @ rozky (многое изменилось в библиотеках Mongo и 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());
    }

}
4 голосов
/ 14 февраля 2016

с пружинной загрузкой 1.3 вы можете использовать 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{
}
3 голосов
/ 23 сентября 2016

Вы можете запустить MongoDB в памяти начиная с версии 3.2.6.С сайта :

Начиная с MongoDB Enterprise версии 3.2.6, механизм хранения в памяти является частью общей доступности (GA) в 64-разрядных сборках.Помимо некоторых метаданных и диагностических данных, механизм хранения в памяти не поддерживает никаких данных на диске, включая данные конфигурации, индексы, учетные данные пользователя и т. Д.

2 голосов
/ 02 мая 2013

Не [только для] для модульных тестов, но прочитайте этот пост в блоге, если вы хотите использовать MongoDB (даже кластер) в качестве развертывания в памяти, если вы используете Linux.

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

Было бы здорово, если бы он был из коробки, как RavenDB.

2 голосов
/ 05 января 2013

Вы также можете проверить этот проект, который имитирует MongoDB в памяти JVM. https://github.com/thiloplanz/jmockmongo Но он все еще в разработке.

2 голосов
/ 26 сентября 2011

Если вы используете Maven, вы можете использовать наши http://mvnrepository.com/artifact/com.wenzani/mongodb-maven-plugin

...