温馨提示:本文翻译自stackoverflow.com,查看原文请点击:scala - How to apply play-evolutions when running tests in play-framework?
playframework scala play-slick playframework-evolutions playframework-2.6

scala - 在游戏框架中运行测试时如何应用游戏进化?

发布于 2020-04-23 15:04:30

在使用Play的Play框架中运行测试时,我遇到了进化方面的问题

  • 适用于Scala的playframework v2.6.6
  • 畅玩v3.0.2
  • play-slick-evolutions v3.0.2

测试如下所示:

class TestFooController extends PlaySpec with GuiceOneServerPerSuite {
  "foo endpoint should store some data" in {
    val wsClient = app.injector.instanceOf[WSClient]
    val url = s"http://localhost:$port/foo"
    val requestData = Json.obj("foo" -> "bar")
    val response = await(wsClient.url(url).post(requestData))
    response.status mustBe OK
  }
}

数据库配置如下所示:

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

假设有一个用于创建表的Evolution脚本,foos并且此脚本在dev模式下运行良好。

运行测试时,将引发以下错误:

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[JdbcSQLException: Table "foos" not found;

foos找不到该表,因此我假设尚未应用数据库演化。

然后,我将数据库配置更改为在dev模式下使用的postgresql。

slick.dbs.default.driver = "slick.driver.PostgresDriver$"
slick.dbs.default.db.driver = "org.postgresql.Driver"
slick.dbs.default.db.url = "jdbc:postgresql://localhost:5432/foo-test"
slick.dbs.default.db.user = "user"
slick.dbs.default.db.password = "password"

通过这种配置,测试工作正常并且数据存储在数据库中,因此数据库的运行就很好。

现在的问题是,测试后没有清理数据库。我想用一个干净的数据库运行每个测试套件。

总结一下。对于H2Db,不应用演化,而对postgresql则应用但不清除。

即使这在 application.test.conf

play.evolutions.autoApply=true
play.evolutions.autoApplyDowns=true

我也试过

play.evolutions.db.default.autoApply=true
play.evolutions.db.default.autoApplyDowns=true

没有效果。

然后,我尝试通过以下方式手动执行此操作:

  def withManagedDatabase[T](block: Database => T): Unit = {
    val dbapi    = app.injector.instanceOf[DBApi]
    val database = dbapi.database("default")
    Evolutions.applyEvolutions(database)
    block(database)
    Evolutions.cleanupEvolutions(database)
  }

然后将测试更改为:

  "foo endpoint should store some data" in withManagedDatabase { _ =>
    ...
  }

对于H2数据库配置,它没有任何作用,foos并抛出与找不到表相同的错误对于postgresql数据库配置,将引发演进异常

play.api.db.evolutions.InconsistentDatabase: Database 'default' is in an inconsistent state![An evolution has not been applied properly. Please check the problem and resolve it manually before marking it as resolved.]

我希望每个测试套件之前都运行进化升级,而每个测试套件之后都运行进化降低。如何做到这一点?

查看更多

提问者
schub
被浏览
12
Rutger Claes 2020-02-07 02:58

您可以使用以下内容在每个套件之前应用演变,然后进行清理:

trait DatabaseSupport extends BeforeAndAfterAll {
  this: Suite with ServerProvider =>

  private lazy val db = app.injector.instanceOf[DBApi]

  override protected def beforeAll(): Unit = {
    super.beforeAll()
    initializeEvolutions(db.database("default"))
  }

  override protected def afterAll(): Unit = {
    cleanupEvolutions(db.database("default"))
    super.afterAll()
  }

  private def initializeEvolutions(database: Database):Unit = {
    Evolutions.cleanupEvolutions(database)
    Evolutions.applyEvolutions(database)
  }

  private def cleanupEvolutions(database: Database):Unit = {
    Evolutions.cleanupEvolutions(database)
  }

}