Как применять ручные разработки в тестах с помощью Slick и Play! 2,4

Я хотел бы вручную запустить мою эволюцию script в начале каждого тестового файла. Я работаю с Play! 2.4 и Slick 3.

В соответствии с документацией, путь, по-видимому, выглядит следующим образом:

Evolutions.applyEvolutions(database)

но мне не удается получить экземпляр моей базы данных. В documentation play.api.db.Databases импортируется, чтобы получить экземпляр базы данных, но если я попытаюсь его импортировать, я получаю эту ошибку: object Databases is not a member of package play.api.db

Как я могу получить экземпляр моей базы данных для запуска эволюции script?

Изменить:, как указано в комментариях, вот весь исходный код, дающий ошибку:

import models._
import org.scalatest.concurrent.ScalaFutures._
import org.scalatest.time.{Seconds, Span}
import org.scalatestplus.play._
import play.api.db.evolutions.Evolutions
import play.api.db.Databases

class TestAddressModel extends PlaySpec with OneAppPerSuite {
   lazy val appBuilder = new GuiceApplicationBuilder()
   lazy val injector = appBuilder.injector()
   lazy val dbConfProvider = injector.instanceOf[DatabaseConfigProvider]

  def beforeAll() = {
    //val database: Database = ???
    //Evolutions.applyEvolutions(database)
  }

  "test" must { 
     "test" in { } 
  } 
}

Ответ 1

Наконец-то я нашел это решение. Я ввожу Guice:

lazy val appBuilder = new GuiceApplicationBuilder()

lazy val injector = appBuilder.injector()

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

(Вам нужно импортировать play.api.db.DBApi.)

И в моих тестах я просто делаю следующее (на самом деле я использую другую базу данных для своих тестов):

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

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

Ответ 2

Учитывая, что вы используете Play 2.4, где эволюции были перемещены в отдельный модуль, вы должны добавить evolutions в зависимости от проекта.

libraryDependencies += evolutions

Ответ 3

Я нахожу, что самый простой способ запуска тестов с использованием применений - использовать FakeApplication и вводить информацию о подключении для БД вручную.

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

Используйте его следующим образом:

"test" in withDB { }

Это позволяет вам, например, использовать базу данных в памяти для ускорения ваших модульных тестов.

Вы можете получить доступ к экземпляру DB как play.api.db.DB, если вам это нужно. Вам также потребуется import play.api.Play.current.

Ответ 4

Используйте FakeApplication, чтобы прочитать конфигурацию вашего БД и предоставить экземпляр БД.

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

Используйте его следующим образом:

"test" in withDB { }

Ответ 5

Чтобы иметь доступ к play.api.db.Databases, вы должны добавить jdbc в свои зависимости:

libraryDependencies += jdbc

Надеюсь, что это поможет некоторым людям, проходящим здесь.

EDIT: тогда код будет выглядеть так:

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

Вы знаете, есть экземпляр БД и можете выполнять запросы на нем:

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

Вы можете видеть больше из docs