我的问题是this one的变体。
由于我的Java Web应用程序项目需要大量读取过滤器/查询以及与GridFS等工具的接口,因此我很难想出以上述解决方案建议的方式使用MongoDB的合理方法。
因此,我正在考虑在我的集成测试中运行MongoDB的嵌入式实例。我希望自动启动(对于每个测试或整个套件),刷新数据库进行每次测试,然后关闭最后。这些测试可能在开发机器和CI服务器上运行,因此我的解决方案也需要可移植。
任何对MongoDB有更多了解的人都可以帮助我了解这种方法的可行性,并且/或者建议任何可能帮助我开始使用的阅读材料吗?
我也对人们对如何处理这个问题的其他建议持开放态度......
答案 0 :(得分:93)
我找到了Embedded 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));
}
}
答案 1 :(得分:18)
有Foursquare产品Fongo。 Fongo是mongo的内存中java实现。它拦截对标准mongo-java-driver的调用,用于查找,更新,插入,删除和其他方法。主要用于轻量级单元测试,您不希望启动mongo进程。
答案 2 :(得分:7)
如果您正在使用Maven,您可能会对我创建的包含flapdoodle.de 'embedded mongo' API的插件感兴趣:
它提供了一个start
目标,您可以使用它来启动您想要的任何版本的MongoDB(例如在pre-integration-test
期间),以及一个将阻止MongoDB的stop
目标(例如在{ {1}})。
使用此插件的真正好处是不需要事先安装MongoDB。 MongoDB二进制文件被下载并存储在post-integration-test
中以供将来构建。
答案 3 :(得分:7)
如果您使用的是sbt和specs2,我为embedmongo编写了相同类型的包装器
答案 4 :(得分:4)
你可以使用 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一起使用。
<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>
================================================ =============================
server.port = 8080
spring.data.mongodb.database=user_db
spring.data.mongodb.port=27017
spring.data.mongodb.host=localhost
================================================ =============================
公共接口UserRepository扩展了MongoRepository {
供参考,所有Java代码使用以下链接:(逐步说明)
答案 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的实际实例。
假实现可能与真实实现完全不同。测试时,您应该努力做到正确。执行速度排在第二位。