Java 运行集成测试时嵌入 MongoDB

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6437226/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 05:54:27  来源:igfitidea点击:

Embedded MongoDB when running integration tests

javamongodbjunitintegration-testingembedded-database

提问by seanhodges

My question is a variation of this one.

我的问题是这个问题的一个变体。

Since my Java Web-app project requires a lot of read filters/queries and interfaces with tools like GridFS, I'm struggling to think of a sensible way to employ MongoDB in the way the above solution suggests.

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

Therefore, I'm considering running an embedded instance of MongoDB alongside my integration tests. I'd like it to start up automatically(either for each test or the whole suite), flush the databasefor every test, and shut downat the end. These tests might be run on development machines as well as the CI server, so my solution will also need to be portable.

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

Can anyone with more knowledge on MongoDB help me get idea of the feasibility of this approach, and/or perhaps suggest any reading material that might help me get started?

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

I'm also open to other suggestions people might have on how I could approach this problem...

我也愿意接受人们可能对我如何解决这个问题提出的其他建议......

采纳答案by Collin Krawll

Here's an updated (for 2019) version of the accepted answer from @rozky(a lot has been changed in both the Mongo and Embedded MongoDB libraries).

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

}

回答by rozky

I have found Embedded MongoDBlibrary which looks quite promising and does what you have asked for.

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

Currently supports MongoDB versions: 1.6.5to 3.1.6, provided the binaries are still available from the configured mirror.

目前支持 MongoDB 版本:1.6.5to 3.1.6,前提是二进制文件仍然可以从配置的镜像中获得。

Here is short example of use, which I have just tried and it works perfectly:

这是使用的简短示例,我刚刚尝试过,效果很好:

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));
    }
}

回答by joelittlejohn

If you're using Maven you may be interested in a plugin I've created that wraps the flapdoodle.de 'embedded mongo' API:

如果您正在使用 Maven,您可能会对我创建的一个插件感兴趣,该插件包装了flappdoodle.de 'embedded mongo' API

embedmongo-maven-plugin

embedmongo-maven-plugin

It provides a startgoal that you can use to start any version of MongoDB you want (e.g. during pre-integration-test), and a stopgoal that will stop MongoDB (e.g. during post-integration-test).

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

The real benefit of using this plugin over others is that there is no requirement for MongoDB to be installed beforehand. MongoDB binaries are downloaded and stored in ~/.embedmongofor future builds.

与其他插件相比,使用此插件的真正好处是不需要事先安装 MongoDB。MongoDB 二进制文件被下载并存储在其中~/.embedmongo以备将来构建。

回答by Aurélien Thieriot

If you are using sbt and specs2, I wrote the same kind of wrapper for embedmongo

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

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

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

回答by zlob

There is Foursquare product Fongo. Fongo is an in-memory java implementation of mongo. It intercepts calls to the standard mongo-java-driver for finds, updates, inserts, removes and other methods. The primary use is for lightweight unit testing where you don't want to spin up a mongo process.

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

回答by Hymanson

In production, you will be using a real database.

在生产中,您将使用真实的数据库。

If you want your tests to reflect how your product behaves in production, use a real instance of Mongo.

如果您希望您的测试反映您的产品在生产中的行为,请使用 Mongo 的真实实例。

A fake implementation may not behave exactly the same as a real one. When testing, you should strive for correctness. Speed of execution comes second.

虚假实现的行为可能与真实实现不同。测试时,您应该争取正确性。执行速度排在第二位。

回答by panser

with spring-boot 1.3 you can use EmbeddedMongoAutoConfiguration

使用 spring-boot 1.3,您可以使用EmbeddedMongoAutoConfiguration

pom.xml

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

回答by Irwin

You can run MongoDB in memory as of version 3.2.6. From the site:

从版本 3.2.6 开始,您可以在内存中运行 MongoDB。从网站

Starting in MongoDB Enterprise version 3.2.6, the in-memory storage engine is part of general availability (GA) in the 64-bit builds. Other than some metadata and diagnostic data, the in-memory storage engine does not maintain any on-disk data, including configuration data, indexes, user credentials, etc.

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

回答by Dheeraj kumar

Not just for unit testing, but also explained how to use inmemory mongodb with rest api.

不仅用于单元测试,还解释了如何将 inmemory mongodb 与 rest api 一起使用。

maven dependency:

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

用户存储库.java

public interface UserRepository extends MongoRepository{

公共接口 UserRepository 扩展了 MongoRepository{

}

}

for reference and all java code use below link:(step by step explanation)

供参考和所有java代码使用以下链接:(分步解释)

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

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

回答by bubbles

Performances are better when executing mongodwith storageEngine='ephemeralForTest'

执行时性能更好mongodstorageEngine='ephemeralForTest'

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