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
Embedded MongoDB when running integration tests
提问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.5
to 3.1.6
, provided the binaries are still available from the configured mirror.
目前支持 MongoDB 版本:1.6.5
to 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 start
goal that you can use to start any version of MongoDB you want (e.g. during pre-integration-test
), and a stop
goal 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 ~/.embedmongo
for 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 编写了相同类型的包装器
回答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代码使用以下链接:(分步解释)
回答by bubbles
Performances are better when executing mongod
with storageEngine='ephemeralForTest'
执行时性能更好mongod
用storageEngine='ephemeralForTest'
new MongodConfigBuilder()
.version(Version.Main.PRODUCTION)
.cmdOptions(new MongoCmdOptionsBuilder()
.useStorageEngine("ephemeralForTest")
.build())
.net(new Net("localhost", port, Network.localhostIsIPv6()))
.build()