Как применить эволюцию вручную в тестах с Slick and Play! 2,4

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

Согласно документации, путь может быть следующим:

Evolutions.applyEvolutions(database)

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

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

Редактировать: как и просили в комментариях, вот весь исходный код с ошибкой:

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

5 ответов

Решение

Я наконец нашел это решение. Я делаю инъекцию с 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"))
}

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

libraryDependencies += evolutions

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

libraryDependencies += jdbc

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

РЕДАКТИРОВАТЬ: код будет выглядеть так:

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

Вы можете увидеть больше из документов

РЕДАКТИРОВАТЬ: опечатка

Используйте 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 { }

Я считаю, что самый простой способ запустить тесты с примененными эволюциями - это использовать 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 { }

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

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

Другие вопросы по тегам