我以为我暂时修复了the problem,但事实证明我仍然遇到问题。
我正在尝试为我的模型层创建一些specs2测试,我想插入一些虚拟对象,然后运行一些查询以确保数据按预期出现。这是我的简单测试:
class ModelSpec extends Specification { override def is = args(sequential = true) ^ super.is object FakeApp extends FakeApplication() running(FakeApp){ println("set up database") val newUser = User( email = "wfbarksdale@gmail.com", username = "weezybizzle", password = "nutterbutter") User.save(newUser) } running(FakeApp) { "User Model" should { "be created and retrieved by username" in { println("finding someone") User.findOneByUsername("weezybizzle") must beSome } "not find non existant user" in { println("finding nobody") User.findOneByUsername("nobody") must beNone } } } }
这是我从单元测试得到的堆栈跟踪:
[info] Compiling 1 Scala source to /www/mojulo3/target/scala-2.9.1/test-classes... set up database finding someone finding nobody [info] ModelSpec [info] [info] User Model should [error] ! be created and retrieved by username [error] IllegalStateException: this Mongo has been closed (DBTCPConnector.java:123) [error] com.mongodb.DBTCPConnector._checkClosed(DBTCPConnector.java:123) [error] com.mongodb.DBTCPConnector.call(DBTCPConnector.java:207) [error] com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:313) [error] com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:298) [error] com.mongodb.DBCollection.findOne(DBCollection.java:682) [error] com.mongodb.DBCollection.findOne(DBCollection.java:661) [error] com.mongodb.casbah.MongoCollectionBase$class.findOne(MongoCollection.scala:225) [error] com.mongodb.casbah.MongoCollection.findOne(MongoCollection.scala:897) [error] com.novus.salat.dao.SalatDAO.findOne(SalatDAO.scala:311) [error] models.User$.findOneByUsername(User.scala:24) [error] test.ModelSpec$$anonfun$3$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$3.apply(ModelSpec.scala:29) [error] test.ModelSpec$$anonfun$3$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$3.apply(ModelSpec.scala:29) [error] test.ModelSpec$$anonfun$3$$anonfun$apply$1$$anonfun$apply$2.apply(ModelSpec.scala:29) [error] test.ModelSpec$$anonfun$3$$anonfun$apply$1$$anonfun$apply$2.apply(ModelSpec.scala:27) [error] ! not find non existant user [error] IllegalStateException: this Mongo has been closed (DBTCPConnector.java:123) [error] com.mongodb.DBTCPConnector._checkClosed(DBTCPConnector.java:123) [error] com.mongodb.DBTCPConnector.call(DBTCPConnector.java:207) [error] com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:313) [error] com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:298) [error] com.mongodb.DBCollection.findOne(DBCollection.java:682) [error] com.mongodb.DBCollection.findOne(DBCollection.java:661) [error] com.mongodb.casbah.MongoCollectionBase$class.findOne(MongoCollection.scala:225) [error] com.mongodb.casbah.MongoCollection.findOne(MongoCollection.scala:897) [error] com.novus.salat.dao.SalatDAO.findOne(SalatDAO.scala:311) [error] models.User$.findOneByUsername(User.scala:24) [error] test.ModelSpec$$anonfun$3$$anonfun$apply$1$$anonfun$apply$6$$anonfun$apply$7.apply(ModelSpec.scala:35) [error] test.ModelSpec$$anonfun$3$$anonfun$apply$1$$anonfun$apply$6$$anonfun$apply$7.apply(ModelSpec.scala:35) [error] test.ModelSpec$$anonfun$3$$anonfun$apply$1$$anonfun$apply$6.apply(ModelSpec.scala:35) [error] test.ModelSpec$$anonfun$3$$anonfun$apply$1$$anonfun$apply$6.apply(ModelSpec.scala:33) [info] [info] [info] Total for specification ModelSpec [info] Finished in 20 ms [info] 2 examples, 0 failure, 2 errors [info] [error] Error: Total 2, Failed 0, Errors 2, Passed 0, Skipped 0 [error] Error during tests: [error] test.ModelSpec [error] {file:/www/mojulo3/}mojulo3/test:test: Tests unsuccessful [error] Total time: 4 s, completed Aug 28, 2012 10:02:33 PM
看起来FakeApp以某种方式与数据库断开连接,而不是重新连接。我查看了Play源代码,似乎应用程序将停止并重新启动,无论它是否实际上是同一个对象。我认为问题可能源于salat onStop()
方法或onStart()
,但我不太确定。
我一直在努力争取这一点,任何帮助,即使只是如何解决问题,都将不胜感激。
答案 0 :(得分:4)
我已经改变了play-salat如何关闭它的连接的实现。
通常,当应用程序停止时关闭所有连接是一件好事,因为当应用程序再次启动时,插件将重新实例化。
问题是我在懒惰的val中创建了mongodb连接,创建了一次连接,当应用程序停止时,它只是在其上调用.close()。
我所做的是解决这个问题,现在连接已关闭,如果再次请求连接,它会创建一个新连接并将其传递给您。
这可以在1.1-SNAPSHOT版本的play-salat中找到,你可以直接使用
resolvers += "OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/"
此版本还包括salat 1.9.1以及对上限集合和gridfs的支持:)
尝试一下,如果任何事情无法按预期发挥作用,请给我一个喊叫。
如果一切顺利,我很快就会发布最终的1.1。
答案 1 :(得分:3)
执行specs2规范有两个阶段:首先创建规范及其所有示例。 然后它被执行。
你应该做的是:
class ModelSpec extends Specification with AroundExamples {
// note the use of sequential here which is simpler than
// overriding the "is" method
sequential
object FakeApp extends FakeApplication()
// this method, defined in the AroundExamples trait
// makes sure that every example is executed "inside"
// the fake app.
def around[R <% Result](r: =>R) = running(FakeApp)(r)
// this will be only executed after the whole spec is created
// if anything fails here, an exception will be caught, reported
// and the rest will not execute
step {
running(FakeApp) {
println("set up database")
val newUser = User(
email = "wfbarksdale@gmail.com",
username = "weezybizzle",
password = "nutterbutter")
User.save(newUser)
}
}
"User Model" should {
"be created and retrieved by username" in {
println("finding someone")
User.findOneByUsername("weezybizzle") must beSome
}
"not find non existant user" in {
println("finding nobody")
User.findOneByUsername("nobody") must beNone
}
}
}
}
我希望有所帮助。
答案 2 :(得分:2)
这是因为它在插件的onStop方法中关闭了MongoDB连接。我已经提交了拉取请求,因此在测试期间不会发生这种情况: