我正在尝试在Play / Scala / ReactiveMongo项目中运行规范测试。安装程序是这样的:
class FeaturesSpec extends Specification {
"Features controller" should {
"create feature from JSON request" in withMongoDb { app =>
// do test
}
}
使用MongoDbFixture如下:
object MongoDBTestUtils {
def withMongoDb[T](block: Application => T): T = {
implicit val app = FakeApplication(
additionalConfiguration = Map("mongodb.uri" -> "mongodb://localhost/unittests")
)
running(app) {
def db = ReactiveMongoPlugin.db
try {
block(app)
} finally {
dropAll(db)
}
}
}
def dropAll(db: DefaultDB) = {
Await.ready(Future.sequence(Seq(
db.collection[JSONCollection]("features").drop()
)), 2 seconds)
}
}
当测试运行时,日志非常嘈杂,抱怨资源已经关闭。虽然测试工作正常,但这很奇怪,我想知道为什么会发生这种情况以及如何解决它。
错误:
[info] application - ReactiveMongoPlugin stops, closing connections...
[warn] play - Error stopping plugin
java.lang.IllegalStateException: Can't get ClosableLazy value after it has been closed
at play.core.ClosableLazy.get(ClosableLazy.scala:49) ~[play_2.11-2.3.7.jar:2.3.7]
at play.api.libs.concurrent.AkkaPlugin.applicationSystem(Akka.scala:71) ~[play_2.11-2.3.7.jar:2.3.7]
at play.api.libs.concurrent.Akka$$anonfun$system$1.apply(Akka.scala:29) ~[play_2.11-2.3.7.jar:2.3.7]
at play.api.libs.concurrent.Akka$$anonfun$system$1.apply(Akka.scala:29) ~[play_2.11-2.3.7.jar:2.3.7]
at scala.Option.map(Option.scala:145) [scala-library-2.11.4.jar:na]
答案 0 :(得分:1)
该异常意味着您在应用程序停止后使用ReactiveMongo插件。
您可能想尝试使用Around
:
class withMongoDb extends Around with Scope {
val db = ReactiveMongoPlugin.db
override def around[T: AsResult](t: => T): Result = try {
val res = t
AsResult.effectively(res)
} finally {
...
}
}
您还应该查看Flapdoodle Embedded Mongo,因为在测试IIRC后您不必删除数据库。
答案 1 :(得分:0)
可能会出现此问题,因为您的测试练习了引用已关闭的MongoDB实例的代码。运行每个Play Specs2测试后,MongoDb连接将被重置,因此您的第一个测试可能会通过,但后续测试可能会对已关闭的实例保持陈旧的引用,从而导致失败。
解决此问题的一种方法是确保在您的应用程序中满足以下条件:
我写了一篇blog帖子,描述了Play控件上下文中问题的解决方案。