Scala 测试时池已关闭(HikariDataSource)
将应用程序迁移到Play 2.4并将依赖项注入应用程序的控制器之后,在运行单元测试时,我得到了“Pool has Shutdown”。受影响的测试如下所示: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.
@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)关闭后尝试使用它。