Monday, September 30, 2013

EmbedMongo and the Play Framework


We would like to use integrations and unit tests that don't require an actual database. As of this writing there are several solutions to this problem with relational databases, however we are using Mongo, a popular NOSQL db.

We have found using embedmongo (https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo) useful for this task.

Here is a sample of how to make this work...

//STEP 1. Add the maven resource into your sbt file
object ApplicationBuild extends Build {
val appDependencies = Seq(
// ...
"de.flapdoodle.embed" % "de.flapdoodle.embed.mongo" % "1.36",
.....
)
val main = play.Project(appName, appVersion, appDependencies).settings(
....
// include the maven repo local here...
resolvers += "maven repo" at "http://repo1.maven.org/maven2/",
....
)
}
view raw gistfile1.scala hosted with ❤ by GitHub
package utils;
import java.io.IOException;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.Mongo;
import com.mongodb.MongoException.Network;
import de.flapdoodle.embed.mongo.MongodStarter;
import de.flapdoodle.embed.mongo.MongodExecutable;
import de.flapdoodle.embed.mongo.MongodProcess;
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;
/**
* Used to start and stop the embedded Mongo server, specifically for testing
* @author codynet
*
*/
public class EmbedMongoHelper {
private static MongodProcess mongod;
private static MongodExecutable mongodExecutable;
/**
* Starts the Mongo Process
* @param port - Standard port for mongo is 27017
* @throws IOException
*/
public static void StartEmbeddedMongo(int port) throws IOException {
//check if mongo is already running
if(mongod!=null && mongod.isProcessRunning()) return;
IMongodConfig mongodConfig = new MongodConfigBuilder()
.version(Version.Main.PRODUCTION).net(new Net(port, true))
.build();
MongodStarter runtime = MongodStarter.getDefaultInstance();
MongodExecutable mongodExecutable = null;
mongodExecutable = runtime.prepare(mongodConfig);
mongod = mongodExecutable.start();
}
/**
* Stopper for Embedded Mongo Process
*/
public static void StopEmbeddedMongo() {
if (mongodExecutable != null)
mongodExecutable.stop();
}
}
view raw gistfile1.java hosted with ❤ by GitHub
import java.io.IOException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import utils.EmbedMongoHelper;
public class MyIntegrationOrUnitTest {
@Before
public void setUp() throws IOException {
EmbedMongoHelper.StartEmbeddedMongo(27017);
//other setup stuff
}
@Test
public void someTest1() {
//....
//assertSome things
}
@Test
public void someTest2() {
//....
//assertSome things
}
@After
public void tearDown() {
//....
EmbedMongoHelper.StopEmbeddedMongo();
}
}
view raw gistfile1.java hosted with ❤ by GitHub

The above describes the quick and dirty steps for starting up the embedded Mongo instance in an integration test.

In practice, I have created an EmbeddedMongo class with a startup and teardown method which makes use of the play framework properties file to populate the appropriate port for testing and to encapsulate the private members mentioned above.

No comments:

Post a Comment