Scala play:H2" HikariDataSource已关闭。"

时间:2016-09-18 23:21:16

标签: scala playframework

我正在尝试使用以下代码在内存数据库中运行我的测试:

class MySpec extends PlaySpec with OneAppPerSuite {

  Databases.withInMemory(
    name = "test",
    urlOptions = Map(
      "MODE" -> "MYSQL",
      "DATABASE_TO_UPPER" -> "false",
      "DB_CLOSE_DELAY" -> "-1"
    ),
    config = Map(
      "logStatements" -> true,
      "lazyInit" -> true,
      "username" -> "sa",
      "password" -> ""
    )
  ) { TestDb =>

    "DataManagementController" should {"connect" in { 
        TestDb.withConnection( conn => 0 )   // do nothing, but connect
    }}

  }
}

但是我收到了这个错误:" HikariDataSource已经关闭"在测试执行之前:

[info] DataManagementController
[info] - should connect *** FAILED ***
[info]   java.sql.SQLException: HikariDataSource HikariDataSource (HikariPool-1) has been closed.
[info]   at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:79)
[info]   at play.api.db.DefaultDatabase.getConnection(Databases.scala:142)
[info]   at play.api.db.DefaultDatabase.withConnection(Databases.scala:152)
[info]   at play.api.db.DefaultDatabase.withConnection(Databases.scala:148)
[info]   at ControllerSpec$$anonfun$1$$anonfun$apply$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(ControllerSpec.scala:37)
[info]   at ControllerSpec$$anonfun$1$$anonfun$apply$1$$anonfun$apply$mcV$sp$1.apply(ControllerSpec.scala:37)
[info]   at ControllerSpec$$anonfun$1$$anonfun$apply$1$$anonfun$apply$mcV$sp$1.apply(ControllerSpec.scala:37)
[info]   at org.scalatest.Transformer$$anonfun$apply$1.apply$mcV$sp(Transformer.scala:22)
[info]   at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85)
[info]   at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
[info]   ...

我做错了什么?

1 个答案:

答案 0 :(得分:1)

当您使用OneAppPerSuite时,Play会为每个套件启动一个应用实例。在您的情况下,您在应用程序准备好之前创建了一个测试数据库。因此,您必须将代码的顺序颠倒为:

"DataManagementController" should {
    "connect" in {
        Databases.withInMemory(
          // Options and config here
        ) { TestDb =>
            TestDb.withConnection( conn => 0 )
        }
    }
}

您还可以封装db初始化部分,以便在需要该db的每个测试中更容易使用:

def testDB[T](block: Database => T) = {
    Databases.withInMemory(
      name = "test",
      urlOptions = Map(
        "MODE" -> "MYSQL",
        "DATABASE_TO_UPPER" -> "false",
        "DB_CLOSE_DELAY" -> "-1"
      ),
      config = Map(
        "logStatements" -> true,
        "lazyInit" -> true,
        "username" -> "sa",
        "password" -> ""
      )
    ) { block }
  }

然后像这样使用它:

"DataManagementController" should {
    "connect" in {
       testDB { db => db.withConnection(conn => 0) }
    }
}

来源:https://www.playframework.com/documentation/2.5.x/ScalaTestingWithDatabases