play framework evolutions scala playframework guice slick play-slick

framework - ¿Cómo ejecutar ScalaTest con Guice DI y Slick?



play framework evolutions (2)

No sé cómo configurar GuiceApplicationBuilder de tal manera que pueda cargar controladores que requieran que se instale un DatabaseConfigProvider .

Me gustaría especificar una base de datos postgres alternativa para la prueba, o una base de datos en memoria (si es posible).

Código

class User extends MySpecs with OneAppPerTest { override def newAppForTest( testData: TestData ) = new GuiceApplicationBuilder() // Somehow bind a database here, I guess? .build() "A test" should "test" in { val result = Application.instanceCache[api.controller.User] .apply( app ) .list()( FakeRequest() ) ... } }

Stacktrace

[info] - should return an entity *** FAILED *** [info] com.google.inject.ConfigurationException: Guice configuration errors: [info] [info] 1) No implementation for play.api.db.slick.DatabaseConfigProvider was bound. [info] while locating play.api.db.slick.DatabaseConfigProvider [info] for parameter 1 at api.controller.User.<init>(User.scala:22) [info] while locating api.controller.User [info] [info] 1 error [info] at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1042) [info] at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1001) [info] at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051) [info] at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:321) [info] at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:316) [info] at play.api.Application$$anonfun$instanceCache$1.apply(Application.scala:234) [info] at play.api.Application$$anonfun$instanceCache$1.apply(Application.scala:234) [info] at play.utils.InlineCache.fresh(InlineCache.scala:69) [info] at play.utils.InlineCache.apply(InlineCache.scala:55) [info] ...


Hay un poco de configuración en este enfoque, pero el resultado final es justo. En primer lugar, comience con la implementación de su propio GuiceApplicationLoader extendiéndolo. Vea mi respuesta como implementarlo . ¿Por qué tu propio cargador de aplicaciones? Puede especificar diferentes configuraciones / módulos por modo Prod/Dev/Test , así como diferentes fuentes de datos. Tu application.conf principal.conf no tendría configurado el origen de datos. En su lugar, lo movería a configuraciones específicas del entorno que de todos modos se fusionarían con la configuración principal mediante el cargador de aplicaciones. Tu dev.conf se vería como sigue:

slick.dbs { default { driver = "slick.driver.PostgresDriver$", db { driver = "org.postgresql.Driver", url = "jdbc:postgresql://localhost:5432/dev", user = "postgres" password = "postgres" } } }

Y el truco ahora es utilizar el mismo nombre de origen de datos, en este caso default , para todas las demás configuraciones (la base de datos url, los controladores, las credenciales, etc. serían diferentes). Con dicha configuración, sus evolutions se aplicarán a su base de datos de prueba y desarrollo. Su test.conf podría verse como sigue:

slick.dbs { default { // in memory configuration } }

En sus pruebas, use WithApplicationLoader con su cargador de aplicaciones personalizado y eso es todo.

@RunWith(classOf[JUnitRunner]) class ApplicationSpec extends Specification { "Application" should { "return text/html ok for home" in new WithApplicationLoader(new CustomApplicationLoader) { val home = route(FakeRequest(routes.ApplicationController.home())).get status(home) must equalTo(OK) contentType(home) must beSome.which(_ == "text/html") } } }

Dentro de la prueba en sí, tiene acceso a la app: Application Valor de la app: Application :

val service = app.injector.instanceOf(classOf[IService])


GuiceApplicationBuilder() agregar una configuración a su GuiceApplicationBuilder() , entonces todo debe ser manejado automáticamente por Play Framework. Algo como esto debería ayudar:

val app = new GuiceApplicationBuilder() .configure( Configuration.from( Map( "slick.dbs.YOURDBNAME.driver" -> "slick.driver.H2Driver$", "slick.dbs.YOURDBNAME.db.driver" -> "org.h2.Driver", "slick.dbs.YOURDBNAME.db.url" -> "jdbc:h2:mem:", "slick.dbs.default.driver" -> "slick.driver.MySQLDriver$", "slick.dbs.default.db.driver" -> "com.mysql.jdbc.Driver" ) ) ) .in(Mode.Test) .build()