运行集成测试时嵌入式MongoDB

sea*_*ges 108 java junit integration-testing embedded-database mongodb

我的问题是这一个的变种.

由于我的Java Web应用程序项目需要大量读取过滤器/查询以及与GridFS等工具的接口,因此我很难想到以上述解决方案建议的方式使用MongoDB的合理方法.

因此,我正在考虑在我的集成测试中运行MongoDB的嵌入式实例.我希望它能自动启动(对于每个测试或整个套件),为每个测试刷新数据库,最后关闭.这些测试可能在开发机器和CI服务器上运行,因此我的解决方案也需要是可移植的.

任何对MongoDB有更多了解的人都能帮助我了解这种方法的可行性,并且/或者建议任何可能帮助我入门的阅读材料吗?

我也对人们对如何处理这个问题的其他建议持开放态度......

roz*_*zky 95

我发现嵌入式MongoDB库看起来非常有前途,并且可以满足您的要求.

目前支持MongoDB版本:1.6.5to 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));
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 小心这个解决方案.它只是收集有关当前操作系统的信息,并从Internet下载适当的特定于平台的MongoDB二进制文件,运行守护程序并执行其他一些配置操作.作为企业解决方案,事实并非如此.模拟可能是唯一真正的选择. (16认同)

zlo*_*lob 18

有Foursquare产品Fongo.Fongo是mongo的内存中java实现.它拦截对标准mongo-java-driver的调用,用于查找,更新,插入,删除和其他方法.主要用于轻量级单元测试,您不希望启动mongo进程.


Col*_*wll 8

这是@rozky接受的答案的更新版本(2019年)(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());
    }

}
Run Code Online (Sandbox Code Playgroud)


joe*_*ohn 7

如果您正在使用Maven,您可能会对我创建的包装flapdoodle.de'嵌入式mongo'API的插件感兴趣:

embedmongo - Maven的插件

它提供了一个start目标,您可以使用它来启动您想要的任何版本的MongoDB(例如在期间pre-integration-test),以及一个stop将停止MongoDB 的目标(例如在期间post-integration-test).

使用此插件的真正好处是不需要事先安装MongoDB.下载并存储MongoDB二进制文件以~/.embedmongo供将来构建.


Aur*_*iot 7

如果您使用sbt和specs2,我为embedmongo编写了相同类型的包装器

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


pan*_*ser 5

在 spring-boot 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>
Run Code Online (Sandbox Code Playgroud)

蒙戈配置

@Configuration
@EnableAutoConfiguration(exclude = { EmbeddedMongoAutoConfiguration.class })
public class MongoConfig{
}
Run Code Online (Sandbox Code Playgroud)