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: 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()
in afterAll()
to mitigate that, but it had no effect. I tried to not run tests in parallel, but no effect either. Where is it that I open db connections without closing them, and where should I call shutdown()
?
N.B. I use Play 2.5.10 and Slick 3.1.
I have a lot of tests (about 500) and I don't get this error, the only difference I have with your code is that I add
and
for the integration tests.
Let me know if it changes anything.
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:
Restart sbt to take changes into account. In IntelliJ, you will want to refresh the project, too.
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
Now you can use
play.api.db.Databases
from jdbc and its methodwithDatabase
to run the evolutions.Finally, call tests requiring a db reset like this:
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:If somebody has a better suggestion, please improve on this answer! I have been struggling for months.