java - 运行集成测试时嵌入式MongoDB
我的问题是这一个的变种。
由于我的Java Web应用程序项目需要大量读取过滤器/查询以及与GridFS等工具的接口,因此我很难想到以上述解决方案建议的方式使用MongoDB的合理方法。
因此,我正在考虑在我的集成测试中运行MongoDB的嵌入式实例。 我希望它能自动启动(对于每个测试或整个套件),为每个测试刷新数据库,最后关闭。 这些测试可能在开发机器和CI服务器上运行,因此我的解决方案也需要是可移植的。
任何对MongoDB有更多了解的人都可以帮助我了解这种方法的可行性,并且/或者建议任何可能帮助我入门的阅读材料吗?
我也对人们对如何处理这个问题的其他建议持开放态度......
13个解决方案
92 votes
我发现嵌入式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));
}
}
rozky answered 2019-07-12T06:54:37Z
18 votes
有Foursquare产品Fongo。Fongo是mongo的内存中java实现。 它拦截对标准mongo-java-driver的调用,用于查找,更新,插入,删除和其他方法。 主要用于轻量级单元测试,您不希望启动mongo进程。
zlob answered 2019-07-12T06:55:02Z
7 votes
如果您正在使用Maven,您可能会对我创建的包装flapdoodle.de'嵌入式mongo'API的插件感兴趣:
embedmongo - Maven的插件
它提供了一个~/.embedmongo目标,您可以使用它来启动您想要的任何版本的MongoDB(例如在pre-integration-test期间),以及将停止MongoDB的stop目标(例如在post-integration-test期间)。
使用此插件的真正好处是不需要事先安装MongoDB。 下载MongoDB二进制文件并将其存储在~/.embedmongo中以供将来构建。
joelittlejohn answered 2019-07-12T06:55:51Z
7 votes
如果您使用sbt和specs2,我为embedmongo编写了相同类型的包装器
[https://github.com/athieriot/specs2-embedmongo]
Aurélien Thieriot answered 2019-07-12T06:56:24Z
4 votes
使用spring-boot 1.3,您可以使用EmbeddedMongoAutoConfiguration
的pom.xml
org.springframework.boot
spring-boot-starter-parent
1.3.2.RELEASE
...
org.springframework.boot
spring-boot-starter-data-mongodb
de.flapdoodle.embed
de.flapdoodle.embed.mongo
${embedded-mongo.version}
MongoConfig
@Configuration
@EnableAutoConfiguration(exclude = { EmbeddedMongoAutoConfiguration.class })
public class MongoConfig{
}
panser answered 2019-07-12T06:56:58Z
3 votes
这是@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 col = db.getCollection("testCollection", BasicDBObject.class);
// when
col.insertOne(new BasicDBObject("testDoc", new Date()));
// then
assertEquals(1L, col.countDocuments());
}
}
Collin Krawll answered 2019-07-12T06:53:58Z
3 votes
从版本3.2.6开始,您可以在内存中运行MongoDB。 从网站:
从MongoDB Enterprise版本3.2.6开始,内存存储 引擎是64位版本中通用可用性(GA)的一部分。 除了一些元数据和诊断数据,内存存储 引擎不维护任何磁盘数据,包括配置 数据,索引,用户凭据等
Irwin answered 2019-07-12T06:57:31Z
2 votes
如果您使用的是maven,可以使用我们的[http://mvnrepository.com/artifact/com.wenzani/mongodb-maven-plugin]
markdsievers answered 2019-07-12T06:57:59Z
2 votes
您还可以检查此项目,该项目模拟JVM内存中的MongoDB。[https://github.com/thiloplanz/jmockmongo]但它仍处于开发阶段。
Sebastien Lorber answered 2019-07-12T06:58:24Z
2 votes
如果您使用Linux,如果您希望将MongoDB(甚至是集群)作为内存部署运行,请阅读此博客文章。
[http://edgystuff.tumblr.com/post/49304254688]
如果像RavenDB一样开箱即可。
Tamir answered 2019-07-12T06:59:04Z
1 votes
与这里提到的embedmongo-maven-plugin类似,还有一个Gradle Mongo插件可用。
与Maven插件一样,它还包装了flapdoodle EmbeddedMongoDb api,并允许您从Gradle构建中运行Mongo的托管实例。
Robert Taylor answered 2019-07-12T06:59:37Z
0 votes
在这里查看此代码示例:[https://github.com/familysyan/embedded-mongo-integ。]没有安装,没有依赖。 它只是一个独立于平台的ant脚本,可以为您下载和设置。 它还可以在测试后清理所有内容。
Edmond answered 2019-07-12T07:00:02Z
-1 votes
在生产中,您将使用真正的数据库。
如果您希望测试反映产品在生产中的表现,请使用Mongo的实际实例。
假实现可能与真实实现不完全相同。 测试时,您应该努力做到正确。 执行速度排在第二位。
Jackson answered 2019-07-12T07:00:42Z