Testing Scala Applications with In-memory mongoDB


Is your test suite taking a large amount of time to run just because your methods need some database queries to be handled? Testing with In-memory databases can save a hell lot of time. In-memory database makes the queries readily available to methods in a matter of milliseconds. In case you are using mongoDB, this blog can help you run your test suite much faster than currently it is.

Adding Configuration

I assume you are already interacting with mongoDB in your application and have included mongoDB driver for that. This plug-in for in-memory mongoDB works with scalatest. I also assume you are using Scalatest as test Toolkit. If you are not, please include the following dependencies to your build to include embedded mongoDB and scalatest.

resolvers ++= Seq(
"Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
)

libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "1.9.2",
"com.github.simplyscala" %% "scalatest-embedmongo" % "0.2.3-SNAPSHOT"
)

Once you have added these lines into your build, resolve these dependencies by running ‘sbt clean compile’ before you proceed.

Preparing the Test Suite

I hope you have written a Test Class to test your code. If you’ve not created any, create one. Your test class must have the following imports:

import org.scalatest.FunSuite
import org.scalatest.BeforeAndAfter
import com.github.simplyscala.MongodProps
import com.github.simplyscala.MongoEmbedDatabase

These imports are necessary to start an in-memory instance of mongoDB before running your Test Suite. Extend your test class with FunSuite (ignore if import is already there) and mix with the traits BeforeAndAfter and MongoEmbedDatabase. For example, have a look at the following code snippet.

class InsertPersonTest extends FunSuite with BeforeAndAfter with MongoEmbedDatabase

Here InsertPersonTest is my test class and I’ve extended it with FunSuite and mixed the traits BeforeAndAfter and MongoEmbedDatabase.

Starting Embedded Mongo

Now the goal is to start the mongoDB instance before running the Test Suite and Stopping it afterwards. To hold the reference of In-memory mongoDB instance, let us declare a variable in the test class as mongoInstance and then include the following before and after statements in your test class. Follow the given code snippet:

var mongoInstance: MongodProps = null //reference holder variable

before {
try{ mongoInstance = mongoStart(27017) } //Try to start mongoDB on default port
catch { case ex:Exception => }
}

after {
mongoStop(mongoInstance) //Stop mongoDB Instance
}

This will start an in-memory instance of mongoDB on the given port, i.e. (27017: default port of mongoDB). Please ensure that no local instance of mongoDB server is running on your machine before running your test suite. Stop the mongoDB server if it is running already and then run your test cases. I hope this will accomplish your purpose of in-memory mongoDB in testing environment.

Example Code

You can clone the example code from the EmbededMongoExample repository on the github. This project illustrates the working of in-memory mongoDB instances with example test cases.

Happy Testing!!

Advertisements

About Manish Mishra

Manish is a Scala Developer at Knoldus Software LLP. He loves to learn and share about Functional Programming, Scala, Akka, Spark.
This entry was posted in Scala and tagged , , , , , , , . Bookmark the permalink.