Как применять ручные разработки в тестах с помощью 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