我正在使用Play 2,Salat(用于mongoDB bindin)编写一个web应用程序。我想在课程模型中测试一些方法(例如,测试我通过id检索正确课程的事实)。问题是,我不想用虚拟课程污染我当前的DB。如何使用Salat和Scala测试来使用假数据库?这是我的一个测试文件。它创建了两个课程,并将其插入到DB中,并对其运行一些测试
LessonSpec extends FlatSpec with ShouldMatchers {
object FakeApp extends FakeApplication()
val newLesson1 = Lesson(
title = "lesson1",
level = 5,
explanations = "expl1",
questions = Seq.empty)
LessonDAO.insert(newLesson1)
val newLesson2 = Lesson(
title = "lesson2",
level = 5,
explanations = "expl2",
questions = Seq.empty)
LessonDAO.insert(newLesson2)
"Lesson Model" should "be retrieved by level" in {
running(FakeApp) {
assert(Lesson.findByLevel(5).size === 2)
}
}
it should "be of size 0 if no lesson of the level is found" in {
running(FakeApp) {
Lesson.findByLevel(4) should be(Nil)
}
}
it should "be retrieved by title" in {
running(FakeApp) {
Lesson.findOneByTitle("lesson1") should be(Some(Lesson("lesson1", 5, "expl1", List())))
}
}
}
我在网上搜索了一下,但找不到一个使用Salat和ScalaTest的好链接或项目。
Salat开发者在这里。我的建议是建立一个单独的仅限测试的数据库。您可以用测试数据填充它,使您的测试数据库处于已知状态(请参阅casbah测试了解如何做到这一点),然后根据需要对其进行测试,清除集合。
我使用的是specs2,而不是scalatest,但原理是一样的——请参阅Salat测试的源代码。
这里有一个很好的测试可以让你开始:https://github.com/novus/salat/blob/master/salat-core/src/test/scala/com/novus/salat/test/dao/SalatDAOSpec.scala
注意,在我的基本规范中,我清除了我的测试数据库——这在每个规范之前都会运行:
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)
}
然后在SalatDAOSpec中,我在范围内运行测试,这些范围创建、填充和/或清除各个集合,以便测试可以在预期状态下运行。一个问题是:如果在同一集合上同时运行测试,它们可能会由于意外状态而失败。解决方案是在独立的专用集合中运行测试,或者强制测试串联运行,这样在不同的测试用例修改集合时,单个集合上的操作就不会相互影响。
如果您发布到Scalatest邮件列表(http://groups.google.com/group/scalatest-users),我相信有人可以推荐正确的设置方法。
在我的应用程序中,我在application.conf中使用一个参数来指定Mongo数据库名称。在初始化FakeApplication时,我会覆盖该参数,这样我的单元测试就可以使用真正的Mongo实例,但看不到任何生产数据。
仔细研究一下我的应用程序的一些细节,我的测试看起来像这样:
// wipe any existing data
db.collectionNames.foreach { colName =>
if (colName != "system.indexes") db.getCollection(colName).drop
}
app = FakeApplication(additionalConfiguration = Map("mongo.db.name" -> "unit-test"))