使用数据库进行测试:“连接过多"; [英] Play tests with database: "Too many connections"
问题描述
要在具有演化的scalatest中提供数据库,我使用默认PlaySpec
的扩展名,该扩展名受
To have a database available in scalatest with evolutions I use this extension of the default PlaySpec
inspired by this SO question:
trait ResetDbSpec extends PlaySpec with BeforeAndAfterAll {
lazy val appBuilder = new GuiceApplicationBuilder()
lazy val injector = appBuilder.injector()
lazy val databaseApi = injector.instanceOf[DBApi]
override def beforeAll() = {
Evolutions.applyEvolutions(databaseApi.database("default"))
}
override def afterAll() = {
Evolutions.cleanupEvolutions(databaseApi.database("default"))
databaseApi.database("default").shutdown()
}
}
它在套件开始时应用数据库演化,并在套件结束时恢复数据库演化.然后测试看起来像
It applies database evolutions when the suite starts, and reverts them when the suite ends. A test then looks like
class ProjectsSpec extends ResetDbSpec with OneAppPerSuite { ...
添加了更多这样的测试后,我碰到了一个点,即当我单独运行它们时,某些测试成功了,并由于以下错误而失败:
After adding more tests like this, I hit a point where some tests that succeed when I run them alone, fail with this error:
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:数据源拒绝建立连接,来自服务器的消息:连接太多"
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"
如上面的代码所示,我尝试添加行
As can be see in the code above, I tried to add the line
databaseApi.database("default").shutdown()
可以缓解这种情况,但是没有效果.我尝试不并行运行测试,但也没有任何效果.在不关闭数据库连接的情况下打开数据库连接应该在哪里?应该在哪里调用 N.B.我使用Play 2.5.10和Slick 3.1. 尽管它不能解决连接泄漏的问题,但我终于设法解决了这个问题: Although it does not answer to what is happening with the connections leakage, I finally managed to hack around this: Add jdbc to you libraryDependencies, even if the Play-Slick FAQ tells you not to do it: 重新启动sbt以考虑更改.在IntelliJ中,您也将要刷新项目. Restart sbt to take changes into account. In IntelliJ, you will want to refresh the project, too. 禁用与play-slick冲突的 jdbc 模块(信用:此答案): Disable the jdbc module that is conflicting with play-slick (credits: this SO answer): 在同一位置,您应该已经配置了 At the same place you should have already configured something like
现在,您可以使用 jdbc 中的 Now you can use 最后,调用需要进行数据库重置的测试,如下所示: Finally, call tests requiring a db reset like this: shutdown()
?推荐答案
# build.sbt
libraryDependencies += jdbc
# application.conf
play.modules.disabled += "play.api.db.DBModule"
slick {
dbs {
default {
driver = "slick.driver.MySQLDriver$"
db.driver = "com.mysql.jdbc.Driver"
db.url = "jdbc:mysql://localhost/test"
db.user = "sa"
db.password = ""
}
}
}
play.api.db.Databases
及其方法withDatabase
来运行进化.play.api.db.Databases
from jdbc and its method withDatabase
to run the evolutions.import org.scalatest.BeforeAndAfterAll
import org.scalatestplus.play.PlaySpec
import play.api.db.{Database, Databases}
import play.api.db.evolutions.Evolutions
trait ResetDbSpec extends PlaySpec with BeforeAndAfterAll {
/**
* Here we use Databases.withDatabase to run evolutions without leaking connections.
* It slows down the tests considerably, though.
*/
private def withTestDatabase[T](block: Database => T) = {
Databases.withDatabase(
driver = "com.mysql.jdbc.Driver",
url = "jdbc:mysql://localhost/test",
name = "default",
config = Map(
"username" -> "sa",
"password" -> ""
)
)(block)
}
override def beforeAll() = {
withTestDatabase { database =>
Evolutions.applyEvolutions(database)
}
}
override def afterAll() = {
withTestDatabase { database =>
Evolutions.cleanupEvolutions(database)
}
}
}
class MySpec extends ResetDbSpec {...}
当然,它在"application.test.conf"和withDatabase()
中都重复了此配置,而且混合了两种不同的API,而不是在谈论性能.还会在每个套件之前和之后添加此名称,这很烦人:
Of course it sucks repeating this config both in "application.test.conf" and in withDatabase()
, plus it mixes two different APIs, not talking about performance. Also it adds this before and after each suite, which is annoying:
[info]应用程序-为数据源默认"创建池
[info]应用程序-关闭连接池.
[info] application - Creating Pool for datasource 'default'
[info] application - Shutting down connection pool.
如果有人有更好的建议,请改进此答案!我已经挣扎了几个月.
If somebody has a better suggestion, please improve on this answer! I have been struggling for months.
这篇关于使用数据库进行测试:“连接过多";的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!