Scala 如何使用Slick and Play在测试中手动应用演变!2.4
我想在每个测试文件的开头手动运行我的进化脚本。我在和Play一起工作!2.4和光滑3 根据文件,出路似乎是:Scala 如何使用Slick and Play在测试中手动应用演变!2.4,scala,playframework,slick-3.0,playframework-evolutions,Scala,Playframework,Slick 3.0,Playframework Evolutions,我想在每个测试文件的开头手动运行我的进化脚本。我在和Play一起工作!2.4和光滑3 根据文件,出路似乎是: Evolutions.applyEvolutions(database) 但我无法获得数据库的实例。在play.api.db.Databases中,导入是为了获取数据库实例,但是如果我尝试导入它,就会出现以下错误:对象数据库不是包play.api.db的成员 如何获取数据库实例以运行evolution脚本 编辑:如评论中所述,以下是给出错误的完整源代码: import models._
Evolutions.applyEvolutions(database)
但我无法获得数据库的实例。在play.api.db.Databases中,导入
是为了获取数据库实例,但是如果我尝试导入它,就会出现以下错误:对象数据库不是包play.api.db的成员
如何获取数据库实例以运行evolution脚本
编辑:如评论中所述,以下是给出错误的完整源代码:
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 { }
}
}
考虑到您正在使用Play 2.4,其中演进被移动到一个单独的模块中,您必须将evolutions
添加到您的项目依赖项中
libraryDependencies += evolutions
- 资料来源:
- 相关承诺:
我发现使用演进运行测试的最简单方法是使用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)
}
例如,这允许您使用内存中的数据库来加速单元测试
如果需要,您可以通过play.api.DB.DB
访问DB实例。您还需要导入play.api.play.current
使用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 { }
"test" in withDB { }
我终于找到了这个解决办法。我向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
)
在我的测试中,我只需执行以下操作(实际上我使用其他数据库进行测试):
要访问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")
你可以从中看到更多
编辑:输入错误你能发布导致错误的源代码吗?这里也会问同样的问题:我对下面的答案有一些问题,一开始似乎是可行的,但我找到了一个不同的解决方案,我在这里引用它而不是复制:。我知道如何启用自动进化,我想做的是为每个测试文件运行evolution脚本,即使没有任何更改(在1.sql文件中)。这就是为什么我想要一个数据库实例,但我不知道在哪里可以使用您的代码。此外,我已经用GuiceApplicationBuilder为我的测试设置了不同的配置。为什么不从每个测试的空白数据库开始,并应用所有的改进呢?否则,如果测试没有将数据库恢复到正确的状态,您将遇到问题。这正是我想要做的!;)(不是内存中的数据库,但我不认为会有什么不同。)我仍然不明白为什么需要直接访问数据库实例-我使用H2DB,每次测试后它都会删除数据库。但是,一旦FakeApplication运行,它就可以作为play.api.db.db
使用。(我知道,可怕的全球状态,游戏开发者正在努力摆脱它)因为我想在真正的PostgreSQL数据库上运行我的测试,特别是因为我使用像postgis和citext这样的扩展。但和您一样,我希望在每个测试开始时重新启动演进(起伏)。您的代码的问题是,由于我使用Slick,我可以使用play.api.db.db获取数据库实例。使用此技术,在编写更多测试后,我会出现“连接太多”错误:。知道漏洞在哪里吗?我想我的回答不够完整。当您拥有这个play.api.db.Database
时,您可以像在文档中一样创建数据库对象,并且在那里有您的数据库实例,您可以在其上使用Evolutions.applyEvolutions(数据库)
您的数据库实例与我在回答中得到的数据库实例有何不同?您的代码的问题是,由于我使用了Slick,我可以使用play.api.db.DBSure获得我的数据库实例,但我在您的第一篇文章中看到,您在使用play.api.db.Databases时遇到了问题,因此我提供了答案。几天前我也遇到了同样的问题,因为我很难找到答案,所以我想我会把它放在这里,以帮助未来的人们。另一种想法是,您的解决方案不适用于内存中的数据库,而我的解决方案可以,通过适当的更改,您可以在play的文档中找到我的linkedIt适用于inMemoryDatabase,类似这样:类InMemoryDbProvider扩展DatabaseConfigProvider{def get[P
val statement = database.getConnection().createStatement()
val resultSet = statement.executeQuery("some_sql_query")