Scala 测试时池已关闭(HikariDataSource)

Scala 测试时池已关闭(HikariDataSource),scala,playframework,specs2,playframework-2.4,hikaricp,Scala,Playframework,Specs2,Playframework 2.4,Hikaricp,将应用程序迁移到Play 2.4并将依赖项注入应用程序的控制器之后,在运行单元测试时,我得到了“Pool has Shutdown”。受影响的测试如下所示: @RunWith(classOf[JUnitRunner]) class ApplicationSpec extends Specification { "Application" should { "doSomething" in running(TestUtil.app) { val myId = IdGen.

将应用程序迁移到Play 2.4并将依赖项注入应用程序的控制器之后,在运行单元测试时,我得到了“Pool has Shutdown”。受影响的测试如下所示:

@RunWith(classOf[JUnitRunner])

class ApplicationSpec extends Specification {
  "Application" should {
    "doSomething" in running(TestUtil.app) {
      val myId = IdGen.newId("someone")
      ...
    }
  }

}
其中IdGen类类似于:

object IdGen {

  def newId(name: String): ClientCredentials = {
    DB.withTransaction("myDb") { implicit conn =>
      ...
    }
  }

}
对具有的DB.withTransaction()调用的测试失败

[error]    Pool has been shutdown (HikariDataSource.java:89)
[error] com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:89)
[error] play.api.db.DefaultDatabase.getConnection(Databases.scala:143)
[error] play.api.db.DefaultDatabase.withConnection(Databases.scala:153)
[error] play.api.db.DefaultDatabase.withTransaction(Databases.scala:162)
[error] play.api.db.DB$.withTransaction(DB.scala:72)
[error] com.example.idGen$.newId...
我正在用初始化TestUtil.app

object TestUtil {

  lazy val app = new GuiceApplicationBuilder()
      .configure(defaultConfig ++ Helpers.inMemoryDatabase("myDB"))
      .bindings(new TestModule) // Mock injections for test
      .build

}
很明显,我缺少一些东西来启动数据库并运行测试,但我不确定是什么

解决了这个问题

尝试用def替换lazy val,如此问题中所回答:

解决了问题


如果有人能解释一下原因,我会很高兴的。

这个问题困扰着我,因为我在代码中保留了应用程序状态。由于每个测试通常都有自己的
FakeApplication
,当在另一个
FakeApplication
实例的上下文中使用时,从一个
FakeApplication
实例中分离状态将导致问题。一个具体的例子是
play.api.play.current
——这需要为每个
FakeApplication
实例重新评估,并且不应该在代码中保存(只评估一次之后)。

您希望每个规范都有一个新的应用程序,这就是使用
def
得到的。使用惰性val时,同一个应用程序实例在测试中持续存在,导致在其生命周期结束且其组件(如Hikari)关闭后尝试使用它。