How to apply manually evolutions in tests with Slick and Play! 2.4

白昼怎懂夜的黑 提交于 2019-12-04 02:33:05

I finally found this solution. I inject with Guice:

lazy val appBuilder = new GuiceApplicationBuilder()

lazy val injector = appBuilder.injector()

lazy val databaseApi = injector.instanceOf[DBApi] //here is the important line

(You have to import play.api.db.DBApi.)

And in my tests, I simply do the following (actually I use an other database for my tests):

override def beforeAll() = {
  Evolutions.applyEvolutions(databaseApi.database("default"))
}

override def afterAll() = {
  Evolutions.cleanupEvolutions(databaseApi.database("default"))
}

Considering that you are using Play 2.4, where evolutions were moved into a separate module, you have to add evolutions to your project dependencies.

libraryDependencies += evolutions

To have access to play.api.db.Databases, you must add jdbc to your dependencies :

libraryDependencies += jdbc

Hope it helps some people passing here.

EDIT: the code would then look like this :

import play.api.db.Databases

val database = Databases(
  driver = "com.mysql.jdbc.Driver",
  url = "jdbc:mysql://localhost/test",
  name = "mydatabase",
  config = Map(
    "user" -> "test",
    "password" -> "secret"
  )
)

You now have an instance of the DB, and can execute queries on it :

val statement = database.getConnection().createStatement()
val resultSet = statement.executeQuery("some_sql_query")

You can see more from the docs

EDIT: typo

I find the easiest way to run tests with evolutions applied is to use FakeApplication, and input the connection info for the DB manually.

def withDB[T](code: => T): T =
  // Create application to run database evolutions
  running(FakeApplication(additionalConfiguration = Map(
    "db.default.driver"   -> "<my-driver-class>",
    "db.default.url"      -> "<my-db-url>",
    "db.default.user"     -> "<my-db>",
    "db.default.password" -> "<my-password>",
    "evolutionplugin"     -> "enabled"
    ))) {
    // Start a db session
    withSession(code)
  }

Use it like this:

"test" in withDB { }

This allows you, for example, to use an in-memory database for speeding up your unit tests.

You can access the DB instance as play.api.db.DB if you need it. You'll also need to import play.api.Play.current.

Use FakeApplication to read your DB configuration and provide a DB instance.

def withDB[T](code: => T): T =
  // Create application to run database evolutions
  running(FakeApplication(additionalConfiguration = Map(
       "evolutionplugin" -> "disabled"))) {
    import play.api.Play.current
    val database = play.api.db.DB
    Evolutions.applyEvolutions(database)
    withSession(code)
    Evolutions.cleanupEvolutions(database)
  }

Use it like this:

"test" in withDB { }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!