在游戏框架中运行测试时如何应用游戏进化? [英] How to apply play-evolutions when running tests in play-framework?

查看:119
本文介绍了在游戏框架中运行测试时如何应用游戏进化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have problems with evolutions when running tests in play framework using

  • scala的playframework v2.6.6
  • play-slick 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"

假设有一个用于创建表foos的Evolution脚本,并且该脚本在开发人员模式下可以正常工作.

Asume there is an evolution script which creates the table foos and this script is working fine in dev mode.

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

When running the test the following error is thrown:

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

找不到表foos,所以我认为尚未应用数据库演化.

The table foos could not be found so I assume that database evolutions have not been applied.

然后我将数据库配置更改为在开发人员模式下使用的postgresql.

Then I changed the database configuration to postgresql which is used in dev mode.

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"

使用此配置,测试工作正常,数据存储在数据库中,因此数据库运行正常.

With this configuration the test work fine and data are stored in the database, so database evolutions ran just fine.

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

Now the problem is, that the database is not cleaned up after tests. I'd like to run each test suite with a clean database.

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

To sum up. With H2Db evolutions are not applied, with postgresql evolutions are applied but not cleaned up.

即使在application.test.conf

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

我也尝试过

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

没有效果.

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

Then I tried to do this manually via:

  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数据库配置,将引发演进异常

For the H2 database configuration it has no effect, the same error that table foos can not be found is thrown. For the postgresql database configuration an evolution exceptions is thrown

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.]

我希望每个测试套件之前都运行进化升级,而每个测试套件之后都运行进化降低.如何实现?

I want evolution ups running before and evolution downs running after each test suite. How can this be achieved?

推荐答案

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

You can use the following to apply evolutions before each suite and clean up afterwards:

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)
  }

}

这篇关于在游戏框架中运行测试时如何应用游戏进化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆