Embedded MongoDB when running integration tests

spring boot embedded mongodb
embedded mongodb c#
embedded mongodb authentication
integration testing with mongodb
embeddedmongoautoconfiguration
mongodb unit test
embedmongo-spring
embedded mongodb for integration tests

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.

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 database for every test, and shut down at 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.

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?

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

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).

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

}

Embedded MongoDB when running integration tests, Here's an updated (for 2019) version of the accepted answer from @rozky (a lot has been changed in  After adding de.flapdoodle.embed.mongo dependency Spring Boot will automatically try to download and start the embedded MongoDB when running tests. The package will be downloaded only once for each version so that subsequent tests run much faster. At this stage we should be able to start and pass the sample JUnit 5 integration test: 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));
    }
}

Integration testing done right with Embedded MongoDB, Integration testing database options. Ideally, our tests should run against a production-like database. Adding a continuous integration tool makes matters worse since more tests would have to be run in parallel. Lesson 1: We need a forked test-suite bound database. When a test suite runs, a database must be started and only made available to that particular test-suite instance. Basically we have the following options: An in-memory embedded database

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.

In-memory MongoDB for unit and integration tests, In-memory MongoDB for unit and integration tests To help setup Embedded MongoDB I also used If you're running separated spring configurations for different unit tests you could  So the idea here is to have the integration tests (empty at the moment) connect to the embedded mongo instance and not the "live" one. However, it doesn't work. I can see the tests connecting to the "live" instance of Mongo, and if I shut that down the build simply fails as it is still attempting to connect to the live instance of Mongo.

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.

Spring Boot With Embedded MongoDB, While developing and testing Spring Boot applications with As the embedded MongoDB runs in memory, it is blazing fast and will Spring Integration Tests with MongoDB Rulez. The main problem is that I have to be able to check mongodb installation (and if not present, install it), start a mongodb instance on startup and shut it down once the process has finished. There's an already developed question here Embedded MongoDB when running integration tests that suggests installing a gradle or maven plugin.

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

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

Spring Boot with Embedded MongoDB, While developing and testing Spring Boot applications with MongoDB as the data store, it is common to  Conclusion. I like both Embedded MongoDB and Fongo. I prefer Fongo to support unit tests. It's easy to setup, fast to startup. But for running integration tests I would suggest using flapdoodle.embed.mongo as you're actually running on a real MongoDB instance giving you the closest to real-life scenario.

flapdoodle-oss/de.flapdoodle.embed.mongo, Embedded MongoDB will provide a platform neutral way for running mongodb in .com/questions/6437226/embedded-mongodb-when-running-integration-tests getDB("test"); DBCollection col = db. An alternative would be to run entire spring boot application in test. In this case your spring boot application will be discovered automatically and embedded mongoDB will be downloaded and started by Spring Boot @RunWith(SpringRunner.class) @SpringBootTest public class YourSpringBootApplicationTests {

Node.js, Not [just for] for unit testings, but read this blog post if you like to run MongoDB (​even a cluster) as in-memory  Embedded MongoDB when running integration tests I want to use In-Memory mode for unit test, is there an in In-Memory mode like RavenDB? mongodb ravendb in-memory-database

java Embedded MongoDB when running integration tests?, Integration Testing is an often overlooked area in Integration Testing with MongoDB & Spring Data can easily setup an embedded MongoDB instance for testing, that we can run all the tests during CI, with minimal build  Spring Integration Tests with MongoDB Rulez Spring integration tests allow you to test functionality against a running application. This article shows proper database set- and clean-up with MongoDB.

Comments
  • If you are using maven, you can use ours mvnrepository.com/artifact/com.wenzani/mongodb-maven-plugin
  • You can also check this project which simulate a MongoDB inside JVM memory. github.com/thiloplanz/jmockmongo But it is still in development.
  • Not [just for] for unit testings, but read this blog post if you like to run MongoDB (even a cluster) as in-memory deployment if you're using Linux. edgystuff.tumblr.com/post/49304254688 Would be great to have it out of the box like RavenDB though.
  • Similar to the embedmongo-maven-plugin mentioned here, there is also a Gradle Mongo Plugin available. Like the Maven plugin it also wraps the flapdoodle EmbeddedMongoDb api and allows you to run a managed instance of Mongo from your Gradle builds.
  • Check this code example here: github.com/familysyan/embedded-mongo-integ. No installation, no dependency. It's simply a platform independent ant script that do download and setup for you. It also cleans up everything after your tests.
  • Repeated start and stop of Embedded mongo for each test fails most of the tests. Its better to start before all the tests and shutdown once all have executed
  • You need to include @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) along with the change above
  • @DBS You could also maybe use a random port so that you can still run your tests concurrently on a fresh embedded mongo instance. See the docs here.
  • Just used this library and it worked perfectly JUnit testing a Mongo API on a Mac. Recommended.
  • +1 excellent find! When I first started using mongodb a year ago, not having a programmatic way to test against a database was one of the downsides. We got around this by having a test instance on every environment, configured through a Java properties file but of course that needed to have mongo installed on every environment. This looks like it will solve all that.
  • Nice! deleted my answer since it's no longer accurate. Anyone any idea how mature this is? I can imagine it having to simulate MongoDB on a very low level would be quite complicated and judging from the source it looks pretty high level.
  • Finally got to play with this in my project and can report that is was incredibly easy to set-up and run. The low-level calls are all part of the official com.mongodb Java API so it is no more complicated than using the regular API.