3

我以为我已经暂时解决了这个问题,但事实证明我仍然有问题。

我正在尝试为我的模型层创建一些 specs2 测试,我想插入一些虚拟对象,然后运行一些查询以确保数据按预期输出。这是我的简单测试的样子:

类 ModelSpec 扩展规范 {

    覆盖 def is = args(sequential = true) ^ super.is

    对象 FakeApp 扩展了 FakeApplication()

    运行(FakeApp){
        println("建立数据库")
        val 新用户 = 用户(
                    电子邮件=“wfbarksdale@gmail.com”,
                    用户名 = "weezybizzle",
                    密码=“坚果黄油”)
        用户保存(新用户)
    }

    运行(FakeApp){
        “用户模型”应该 {
            {中的“由用户名创建和检索”
                println("找人")
                User.findOneByUsername("weezybizzle") 必须是Some
            }
            {中的“找不到不存在的用户”
                println("找不到人")
                User.findOneByUsername("nobody") 必须是None
            }
        }
    }
}

这是我从单元测试中获得的堆栈跟踪:

[信息] 将 1 个 Scala 源代码编译到 /www/mojulo3/target/scala-2.9.1/test-classes...
设置数据库
找人
找不到人
[信息] 模型规格
[信息]
[信息] 用户模型应该
[错误] !由用户名创建和检索
[错误] IllegalStateException: 这个 Mongo 已经关闭 (DBTCPConnector.java:123)
[错误] com.mongodb.DBTCPConnector._checkClosed(DBTCPConnector.java:123)
[错误] com.mongodb.DBTCPConnector.call(DBTCPConnector.java:207)
[错误] com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:313)
[错误] com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:298)
[错误] com.mongodb.DBCollection.findOne(DBCollection.java:682)
[错误] com.mongodb.DBCollection.findOne(DBCollection.java:661)
[错误] com.mongodb.casbah.MongoCollectionBase$class.findOne(MongoCollection.scala:225)
[错误] com.mongodb.casbah.MongoCollection.findOne(MongoCollection.scala:897)
[错误] com.novus.salat.dao.SalatDAO.findOne(SalatDAO.scala:311)
[错误] models.User$.findOneByUsername(User.scala:24)
[错误] test.ModelSpec$$anonfun$3$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$3.apply(ModelSpec.scala:29)
[错误] test.ModelSpec$$anonfun$3$$anonfun$apply$1$$anonfun$apply$2$$anonfun$apply$3.apply(ModelSpec.scala:29)
[错误] test.ModelSpec$$anonfun$3$$anonfun$apply$1$$anonfun$apply$2.apply(ModelSpec.scala:29)
[错误] test.ModelSpec$$anonfun$3$$anonfun$apply$1$$anonfun$apply$2.apply(ModelSpec.scala:27​​)
[错误] !找不到不存在的用户
[错误] IllegalStateException: 这个 Mongo 已经关闭 (DBTCPConnector.java:123)
[错误] com.mongodb.DBTCPConnector._checkClosed(DBTCPConnector.java:123)
[错误] com.mongodb.DBTCPConnector.call(DBTCPConnector.java:207)
[错误] com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:313)
[错误] com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:298)
[错误] com.mongodb.DBCollection.findOne(DBCollection.java:682)
[错误] com.mongodb.DBCollection.findOne(DBCollection.java:661)
[错误] com.mongodb.casbah.MongoCollectionBase$class.findOne(MongoCollection.scala:225)
[错误] com.mongodb.casbah.MongoCollection.findOne(MongoCollection.scala:897)
[错误] com.novus.salat.dao.SalatDAO.findOne(SalatDAO.scala:311)
[错误] models.User$.findOneByUsername(User.scala:24)
[错误] test.ModelSpec$$anonfun$3$$anonfun$apply$1$$anonfun$apply$6$$anonfun$apply$7.apply(ModelSpec.scala:35)
[错误] test.ModelSpec$$anonfun$3$$anonfun$apply$1$$anonfun$apply$6$$anonfun$apply$7.apply(ModelSpec.scala:35)
[错误] test.ModelSpec$$anonfun$3$$anonfun$apply$1$$anonfun$apply$6.apply(ModelSpec.scala:35)
[错误] test.ModelSpec$$anonfun$3$$anonfun$apply$1$$anonfun$apply$6.apply(ModelSpec.scala:33)
[信息]  
[信息]  
[信息] 规范 ModelSpec 的总计
[信息] 在 20 毫秒内完成
[信息] 2 个示例,0 个失败,2 个错误
[信息]
[错误] 错误:总计 2,失败 0,错误 2,通过 0,跳过 0
[错误] 测试期间的错误:
[错误] test.ModelSpec
[错误] {file:/www/mojulo3/}mojulo3/test:test: 测试不成功
[错误] 总时间:4 秒,2012 年 8 月 28 日 10:02:33 PM 完成

看起来 FakeApp 以某种方式与数据库断开连接,而不是重新连接。我查看了播放源,似乎应用程序将停止并重新启动,无论它是否实际上是同一个对象。我认为这个问题可能源于salatonStop()方法,或者onStart()我不太确定。

我已经为此苦苦挣扎了一段时间,任何帮助,即使只是关于如何推理问题,将不胜感激。

4

3 回答 3

4

我已经改变了 play-salat 如何关闭它的连接的实现。

通常在应用程序停止时关闭所有连接是一件好事,因为当应用程序再次启动时插件将被重新实例化。

问题是我在一个惰性 val 中创建了 mongodb 连接,该连接创建了一次,当应用程序停止时,它只需调用 .close() 就可以了。

我所做的修复是连接现在已关闭,如果您再次请求连接,它会创建一个新连接并将其传递给您。

这一切都在 play-salat 的 1.1-SNAPSHOT 版本中可用,您可以通过添加直接使用它

resolvers += "OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/"

此版本还包括 salat 1.9.1 和对 capped collections 和 gridfs 的支持 :)

试试看,如果有任何事情没有按预期工作,请大声告诉我。

如果一切看起来不错,我将很快发布最终的 1.1。

于 2012-09-07T08:55:27.563 回答
3

执行 specs2 规范有 2 个阶段:首先创建规范及其所有示例。然后它被执行。

你应该做的是:

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
      }
    }
  }
}

我希望这会有所帮助。

于 2012-08-29T02:39:22.460 回答
2

这是因为它在插件的 onStop 方法中关闭了 MongoDB 连接。我已经提交了一个拉取请求,以便在测试期间不会发生这种情况:

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

于 2012-08-30T15:10:39.717 回答