【问题标题】:How to reset the in memory database in tests with play2, slick3, specs2如何使用 play2、slick3、specs2 在测试中重置内存数据库
【发布时间】:2016-01-01 19:02:02
【问题描述】:

这是一个 play 2.4 应用程序,使用规范 2 和 slick 3.1。 在我的测试过程中,我使用了一个带有演变的内存数据库。我的问题是:目前,内存数据库在所有测试中都保持活动状态,并且在每个测试用例之后不会重置为初始空状态。

我当前的代码如下所示:

package test

import play.api.test._
import play.api.test.Helpers._
import services.ProjectService
import scala.concurrent.Await
import scala.concurrent.duration.Duration
import org.specs2.mutable._
import scala.concurrent.ExecutionContext.Implicits.global
import testhelpers.Injector


class ModelSpec extends Specification {

  import models._

  val projectService = Injector.inject[ProjectService]

  "A project" should {

    "be inserted" in {
      running(FakeApplication(additionalConfiguration = inMemoryDatabase())) {

        val action = projectService.create("A")
          .flatMap(_ => projectService.all)

        val result = Await.result(action, Duration.Inf)

        result must be_==(List(Project(1, "A")))
      }
    }

    "be inserted2" in {
      running(FakeApplication(additionalConfiguration = inMemoryDatabase())) {

        val action = projectService.create("A")
          .flatMap(_ => projectService.all)

        val result = Await.result(action, Duration.Inf)

        result must be_==(List(Project(1, "A")))
      }
    }


  }

}

第一次测试通过。第二个测试失败并出现错误: List(Project(1,A), Project(2,A)) is not equal to List(Project(1,A)) (ModelSpec.scala:42) 因为内存数据库被保留测试用例之间。

您可以在此处找到示例项目:https://github.com/nemoo/play-slick3-example

如何为每个测试用例创建一个新的数据库?

【问题讨论】:

标签: scala playframework dependency-injection slick specs2


【解决方案1】:

这是implementation of imMemoryDatabase

  def inMemoryDatabase(name: String = "default", options: Map[String, String] = Map.empty[String, String]): Map[String, String] = {
    val optionsForDbUrl = options.map { case (k, v) => k + "=" + v }.mkString(";", ";", "")

    Map(
      ("db." + name + ".driver") -> "org.h2.Driver",
      ("db." + name + ".url") -> ("jdbc:h2:mem:play-test-" + scala.util.Random.nextInt + optionsForDbUrl)
    )
  }

您可以看到它正在设置 db.whatever 配置值,但 Play Slick uses slick.dbs.whatever,所以这对您没有帮助。以下是 Play Slick 的用途:

# Default database configuration
slick.dbs.default.driver="slick.driver.H2Driver$"
slick.dbs.default.db.driver="org.h2.Driver"
slick.dbs.default.db.url="jdbc:h2:mem:play"

您可能想要创建自己的inMemorySlickDatabase(使用inMemoryDatabase 的实现作为灵感),设置适当的配置值。

【讨论】:

  • 好的,我试过了。创建了我自己的 inMemorySlickDatabase 并在测试中使用它。问题还是一样。第一个测试通过,第二个测试失败并出现与之前相同的错误。
【解决方案2】:

我创建了自己的 def 来为 slick/h2 设置东西,这似乎工作正常。

  def inMemoryDatabaseSlick(name: String = "default", options: Map[String, String] = Map.empty[String, String]): Map[String, String] = {
val optionsForDbUrl = options.map { case (k, v) => k + "=" + v }.mkString(";", ";", "")

Map(
  ("slick.dbs." + name + ".driver") -> "slick.driver.H2Driver$",
  ("slick.dbs." + name + ".db.driver") -> "org.h2.Driver",
  ("slick.dbs." + name + ".db.url") -> ("jdbc:h2:mem:play-test-" + scala.util.Random.nextInt + optionsForDbUrl)
)

}

但是我现在遇到的问题是我的 H2 DB 是空的,我看不到任何尝试将进化应用到它来填充它。我应该期望这行得通吗?还是我应该自己创建表格?

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-17
  • 2013-09-08
  • 1970-01-01
  • 2016-01-15
  • 1970-01-01
  • 2013-11-05
  • 1970-01-01
相关资源
最近更新 更多