play integracion framework continua application scala playframework scalatest

scala - integracion - play framework web server



Pruebas funcionales en Play 2.4.6 cuando se utiliza el tiempo de compilaciĆ³n DI (5)

Está recibiendo un error porque las pruebas ni siquiera pueden iniciar una aplicación. Eso está sucediendo porque estás usando Dependency Injection en tus controladores (como sugiere el mensaje de error) y necesitas declararlos como classes , en lugar de como objects . Como puedes ver en los documentos :

package controllers import play.api.mvc._ class Application extends Controller { def index = Action { Ok("It works!") } }

Si tu controlador tiene alguna dependencia para ser inyectado, debes usar la anotación @Inject en tu constructor de controlador (de nuevo, por favor mira los documentos ). Por ejemplo:

package controllers import play.api.mvc._ import play.api.libs.ws._ import javax.inject._ class Application @Inject() (ws: WSClient) extends Controller { // ... }

También puede leer los documentos de Inyección de Dependencia de Tiempo de Compilación si lo está usando en lugar del tiempo de ejecución DI.

Estoy usando Play 2.4.6 con inyección de dependencia de tiempo de compilación y ScalaTest. El constructor del controlador tiene pocos parámetros, y en un ApplicationLoader lo creo. Aquí está el código:

class BootstrapLoader extends ApplicationLoader { def load(context: Context) = { new AppComponents(context).application } } class AppComponents(context: Context) extends BuiltInComponentsFromContext(context) with NingWSComponents { lazy val router = new Routes(httpErrorHandler, authenticationController, applicationController, assets) lazy val applicationController = new controllers.Application() lazy val authenticationController = new controllers.Authentication()(configuration, wsApi.client) lazy val assets = new controllers.Assets(httpErrorHandler) } class Authentication(implicit configuration: Configuration, val ws: WSClient) extends Controller { def login = Action { implicit request => Unauthorized(s"${redirectUrl}") } } class AuthenticationSpec extends PlaySpec with OneAppPerSuite { implicit val configuration: Configuration = app.configuration implicit val wsClient: WSClient = WS.client(app) "when user not logged-in" should { "return Status code Unauthorized(401) with redirect url" in { 1 mustEqual 2 } } }

Cuando ejecuto la prueba recibo el siguiente error:

[info] Exception encountered when attempting to run a suite with class name: controllers.AuthenticationSpec *** ABORTED *** [info] com.google.inject.ProvisionException: Unable to provision, see the following errors: [info] [info] 1) Could not find a suitable constructor in controllers.Authentication. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private. [info] at controllers.Authentication.class(Authentication.scala:19) [info] while locating controllers.Authentication [info] for parameter 1 at router.Routes.<init>(Routes.scala:35) [info] while locating router.Routes [info] while locating play.api.test.FakeRouterProvider [info] while locating play.api.routing.Router [info] [info] 1 error [info] at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1025) [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$class.routes(Application.scala:112) [info] at play.api.test.FakeApplication.routes(Fakes.scala:197) [info] at play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:90) [info] at play.api.Play$$anonfun$start$1.apply(Play.scala:87) [info] at play.api.Play$$anonfun$start$1.apply(Play.scala:87) [info] at play.utils.Threads$.withContextClassLoader(Threads.scala:21)

FakeApplication usa GuiceApplicationBuilder , que por supuesto no funciona.

¿Qué debo hacer para ejecutar tales pruebas?

Gracias


Estoy enfrentando el mismo problema que tú. No tengo una solución satisfactoria, la siguiente es una mera solución: terminé poniendo

implicit def client:WSClient = NingWSClient()

en mi clase WithApplicationLoader

También encontré https://github.com/leanovate/play-mockws que le permite simular las llamadas de ws. Pero eso no es lo que queremos aquí.




override implicit lazy val app = new BootstrapLoader().load( ApplicationLoader.createContext( new Environment( new File("."), ApplicationLoader.getClass.getClassLoader, Mode.Test)))

Funciona en Play 2.5.1