Play tests with database: “Too many connections”

两盒软妹~` 提交于 2019-12-01 17:06:10

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

databaseApi.database("default").getConnection().close()

and

Play.stop(fakeApplication)

for the integration tests.

Let me know if it changes anything.

JulienD

Although it does not answer to what is happening with the connections leakage, I finally managed to hack around this:

  1. Add jdbc to you libraryDependencies, even if the Play-Slick FAQ tells you not to do it:

    # build.sbt
    libraryDependencies += jdbc
    

    Restart sbt to take changes into account. In IntelliJ, you will want to refresh the project, too.

  2. Disable the jdbc module that is conflicting with play-slick (credits: this SO answer):

    # application.conf
    play.modules.disabled += "play.api.db.DBModule"
    

    At the same place you should have already configured something like

    slick {
      dbs {
        default {
          driver = "slick.driver.MySQLDriver$"
          db.driver = "com.mysql.jdbc.Driver"
          db.url = "jdbc:mysql://localhost/test"
          db.user = "sa"
          db.password = ""
        }
      }
    }
    
  3. Now you can use 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)
        }
      }
    
    }
    
  4. Finally, call tests requiring a db reset like this:

    class MySpec extends ResetDbSpec {...}
    

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] 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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!