I am using Play 2.8, play-slick 5.0, and play-slick-evolutions 5.0 connecting to a MySQL Database.
I’m trying to understand how I can write unit tests that talk to a database and use the evolution system to get the DB in a fresh state. I tried using cleanupEvolutions
and applyEvoluions
but I can’t get a play.api.db.Database instance. I assume because I’m using slick I can’t get a Database instance like it wants. How should I be setting this up?
For reference, here is the spec I’ve got together:
import org.specs2.mutable._
import org.specs2.runner._
import org.junit.runner._
import models.AdminRepository
import models.generated.Tables.AdminsRow
import org.specs2.execute.AsResult
import org.specs2.execute.Result
import play.api.db.Database
import play.api.test._
import play.api.Application
import play.api.test.Helpers._
import play.api.test.FutureAwaits
import play.api.db.evolutions._
import play.api.db.slick.evolutions
abstract class TestCase extends WithApplication with Injecting {
/** Before each test, clean the DB and setup the structure again */
override def around[T: AsResult](t: => T): Result = super.around {
val db = inject[Database]
Evolutions.cleanupEvolutions(db)
Evolutions.applyEvolutions(db)
t
}
}
@RunWith(classOf[JUnitRunner])
class AdminRepositorySpec extends PlaySpecification {
"Admin Repository" should {
"find what was saved" in new TestCase {
val app2dao = Application.instanceCache[AdminRepository]
val dao: AdminRepository = app2dao(app)
val email = "test-admin@yahoo.com"
val newrow: Option[AdminsRow] = await(dao.create(email, "pass1"))
val foundRow: Option[AdminsRow] = await(dao.findByEmail(email))
foundRow.isDefined shouldEqual true
foundRow.get.email shouldEqual email
}
}
}
And the error message I get when I sbt test
with the above code
[error] ! find what was saved
[error] com.google.inject.ConfigurationException: Guice configuration errors:
[error]
[error] 1) No implementation for play.api.db.Database was bound.
[error] while locating play.api.db.Database
[error]
[error] 1 error (InjectorImpl.java:1120)
[error] com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1120)
[error] com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1078)
[error] com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1131)
[error] play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:436)
[error] play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:431)
[error] play.api.inject.ContextClassLoaderInjector.$anonfun$instanceOf$2(Injector.scala:119)
[error] play.api.inject.ContextClassLoaderInjector.withContext(Injector.scala:128)
[error] play.api.inject.ContextClassLoaderInjector.instanceOf(Injector.scala:119)
[error] play.api.test.Injecting.inject(Helpers.scala:700)
[error] play.api.test.Injecting.inject$(Helpers.scala:699)
[error] TestCase.inject(AdminRepositorySpec.scala:15)
[error] TestCase.$anonfun$around$1(AdminRepositorySpec.scala:20)
[error] play.api.test.WithApplication.$anonfun$around$2(Specs.scala:58)
[error] play.api.test.PlayRunners.$anonfun$running$2(Helpers.scala:84)
[error] play.api.test.PlayRunners.runSynchronized(Helpers.scala:59)
[error] play.api.test.PlayRunners.runSynchronized$(Helpers.scala:53)
[error] play.api.test.Helpers$.runSynchronized(Helpers.scala:672)
[error] play.api.test.PlayRunners.running(Helpers.scala:82)
[error] play.api.test.PlayRunners.running$(Helpers.scala:80)
[error] play.api.test.Helpers$.running(Helpers.scala:672)
[error] play.api.test.WithApplication.around(Specs.scala:58)
[error] TestCase.around(AdminRepositorySpec.scala:19)
[error] play.api.test.WithApplication.delayedInit(Specs.scala:50)
[error] AdminRepositorySpec$$anon$1.<init>(AdminRepositorySpec.scala:32)
[error] AdminRepositorySpec.$anonfun$new$2(AdminRepositorySpec.scala:32)
Thanks in advance to anyone who can help.