运行集成测试时嵌入式MongoDB

时间:2011-06-22 08:48:57

标签: java mongodb junit integration-testing embedded-database

我的问题是this one的变体。

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

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

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

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

16 个答案:

答案 0 :(得分:93)

我找到了Embedded MongoDB库,看起来非常有前途,并且做了你所要求的。

目前支持MongoDB版本:1.6.53.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));
    }
}

答案 1 :(得分:18)

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

答案 2 :(得分:7)

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

embedmongo-maven-plugin

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

使用此插件的真正好处是不需要事先安装MongoDB。 MongoDB二进制文件被下载并存储在post-integration-test中以供将来构建。

答案 3 :(得分:7)

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

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

答案 4 :(得分:4)

使用spring-boot 1.3

你可以使用 EmbeddedMongoAutoConfiguration

<强>的pom.xml

MAX(`ID`) and not `MAX(ID)`

<强> MongoConfig

<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>

答案 5 :(得分:3)

从版本3.2.6开始,您可以在内存中运行MongoDB。来自site

  

从MongoDB Enterprise版本3.2.6开始,内存存储   引擎是64位版本中通用可用性(GA)的一部分。   除了一些元数据和诊断数据,内存存储   引擎不维护任何磁盘数据,包括配置   数据,索引,用户凭证等

答案 6 :(得分:3)

这是accepted answer from @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());
    }

}

答案 7 :(得分:2)

如果您使用的是maven,则可以使用我们的http://mvnrepository.com/artifact/com.wenzani/mongodb-maven-plugin

答案 8 :(得分:2)

您还可以检查此项目,该项目模拟JVM内存中的MongoDB。 https://github.com/thiloplanz/jmockmongo 但它仍在开发中。

答案 9 :(得分:2)

对于单元测试不是[仅仅],但是如果您想使用Linux运行MongoDB(甚至是集群)作为内存部署,请阅读此博客文章。

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

如果像RavenDB一样开箱即可。

答案 10 :(得分:1)

与此处提到的embedmongo-maven-plugin类似,还有一个Gradle Mongo Plugin可用。

与Maven插件一样,它也包含flapdoodle EmbeddedMongoDb api,并允许您从Gradle构建中运行Mongo的托管实例。

答案 11 :(得分:0)

在此处查看此代码示例:https://github.com/familysyan/embedded-mongo-integ。没有安装,没有依赖。它只是一个独立于平台的ant脚本,可以为您下载和设置。它还会在测试后清理所有内容。

答案 12 :(得分:0)

不仅用于单元测试,还介绍了如何将内存mongodb与rest api一起使用。

maven依赖项:

        <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>
        </dependency>

================================================ =============================

application.properties

server.port = 8080
spring.data.mongodb.database=user_db
spring.data.mongodb.port=27017
spring.data.mongodb.host=localhost

================================================ =============================

UserRepository.java

公共接口UserRepository扩展了MongoRepository {

}

供参考,所有Java代码使用以下链接:(逐步说明)

https://www.youtube.com/watch?v=2Tq2Q7EzhSA&t=7s

答案 13 :(得分:0)

使用mongod执行storageEngine='ephemeralForTest'时,性能会更好

new MongodConfigBuilder()
    .version(Version.Main.PRODUCTION)
    .cmdOptions(new MongoCmdOptionsBuilder()
         .useStorageEngine("ephemeralForTest")
         .build())
    .net(new Net("localhost", port, Network.localhostIsIPv6()))
    .build()

答案 14 :(得分:0)

要运行嵌入式 mongodb 进行集成测试,需要以下 maven 依赖项:

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.5.2</version>
        </dependency>

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

尝试使用以下为 EmbeddedMongoAutoConfiguration 剪下的代码:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class EmbeddedMongoApplication {

    public static void main(String[] args) {
         System.setProperty("os.arch", "x86_64");
         SpringApplication.run(EmbeddedMongoApplication.class, args);
    }
    
    @Bean
    public EmbeddedMongoAutoConfiguration embeddedMongoAutoConfiguration(MongoProperties mongoProperties) {
        return new EmbeddedMongoAutoConfiguration(mongoProperties);
    }
}

注意:

嵌入式 mongodb 将下载到以下路径。因此,请考虑该路径具有适当的权限。

Linux : $HOME/.embedmongo/linux/mongodb-linux-x86_64-3.2.2.tgz
Windows : C:\Users\<username>\.embedmongo\win32\mongodb-win32-x86_64-3.x.x.zip

答案 15 :(得分:-1)

在制作中,您将使用真实的数据库。

如果您希望测试反映产品在生产中的表现,请使用Mongo的实际实例。

假实现可能与真实实现完全不同。测试时,您应该努力做到正确。执行速度排在第二位。