Embedded MongoDB when running integration tests
Solution 1:
I have found Embedded MongoDB library which looks quite promising and does what you have asked for.
Currently supports MongoDB versions: 1.6.5
to 3.1.6
, provided the binaries are still available from the configured mirror.
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));
}
}
Solution 2:
Here's an updated (for 2022) version of the accepted answer from @rozky (a lot has been changed in both the Mongo and Embedded MongoDB libraries).
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.MongodConfig;
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;
MongodConfig mongodConfig = MongodConfig.builder()
.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());
}
}
Solution 3:
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.
Solution 4:
If you're using Maven you may be interested in a plugin I've created that wraps the flapdoodle.de 'embedded mongo' API:
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
).
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.
Solution 5:
If you are using sbt and specs2, I wrote the same kind of wrapper for embedmongo
https://github.com/athieriot/specs2-embedmongo