仍然无法对Salat / Casbah的FakeApp进行多次测试

时间:2012-08-29 02:10:14

标签: mongodb playframework-2.0 casbah specs2 salat

我以为我暂时修复了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(),但我不太确定。

我一直在努力争取这一点,任何帮助,即使只是如何解决问题,都将不胜感激。

3 个答案:

答案 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连接。我已经提交了拉取请求,因此在测试期间不会发生这种情况:

https://github.com/leon/play-salat/pull/27