How to test methods based on Salat with ScalaTest How to test methods based on Salat with ScalaTest mongodb mongodb

How to test methods based on Salat with ScalaTest


Salat developer here. My recommendation would be to have a separate test only database. You can populate it with test data to put your test database in a known state - see the casbah tests for how to do this - and then test against it however you like, clearing out collections as necessary.

I use specs2, not scalatest, but the principle is the same - see the source code for the Salat tests.

Here's a good test to get you started:https://github.com/novus/salat/blob/master/salat-core/src/test/scala/com/novus/salat/test/dao/SalatDAOSpec.scala

Note that in my base spec I clear out my test database - this gets run before each spec:

trait SalatSpec extends Specification with Logging {  override def is =    Step {      //      log.info("beforeSpec: registering BSON conversion helpers")      com.mongodb.casbah.commons.conversions.scala.RegisterConversionHelpers()      com.mongodb.casbah.commons.conversions.scala.RegisterJodaTimeConversionHelpers()    } ^      super.is ^      Step {        //        log.info("afterSpec: dropping test MongoDB '%s'".format(SalatSpecDb))        MongoConnection().dropDatabase(SalatSpecDb)      }

And then in SalatDAOSpec, I run my tests inside scopes which create, populate and/or clear out individual collections so that the tests can run in an expected state. One hitch: if you run your tests concurrently on the same collection, they may fail due to unexpected state. The solution is either to run your tests in isolated special purpose collections, or to force your tests to run in series so that operations on a single collection don't step on each other as different test cases modify the collection.

If you post to the Scalatest mailing list (http://groups.google.com/group/scalatest-users), I'm sure someone can recommend the correct way to set this up.


In my applications, I use a parameter in application.conf to specify the Mongo database name. When initializing my FakeApplication, I override that parameter so that my unit tests can use a real Mongo instance but do not see any of my production data.

Glossing over a few details specific to my application, my tests look something like this:

// wipe any existing datadb.collectionNames.foreach { colName =>  if (colName != "system.indexes") db.getCollection(colName).drop}app = FakeApplication(additionalConfiguration = Map("mongo.db.name" -> "unit-test"))