2012-04-01 8 views
5

Gioco con Play 2.0, versione di Scala. Attualmente analizzo Zentasks sample app.Come testare l'app di esempio Zentasks da Play 2.0

Una parte di questa app è il meccanismo di autenticazione per lo più coperto nel tratto Secured. Mi chiedo come posso testare azioni sicure, es. index da Projects controller.

Per azione non-assicurato, probabilmente sarei fare qualcosa di simile

val result = controllers.Projects.index(FakeRequest()) 

per eseguire un'azione e ottenere il suo risultato.

Cosa devo fare in caso di azione protetta?

Disclaimer: Sono assolutamente nuovo sia per Scala che per Play, quindi tutti i suggerimenti sono molto preziosi. Grazie!

risposta

1

ok, non sono un grande esperto, ma ecco un'idea.

Creare un trait InSecure trait extends Secured che sovrascrive le azioni Protette e consente sempre l'accesso. Quindi è possibile effettuare un test object InSecureProjects extends Projects with InSecture, questo dovrebbe ignorare solo i controlli di sicurezza e consentire di testare le azioni senza alcuna sicurezza.

Ora, anziché eseguire i test su Projects, li si esegue su InSecureProjects. Puoi fare esattamente lo stesso per gli altri controller protetti.

non ho ancora testato, quindi fatemi sapere se funziona;)

2

C'è una fix for the integrated approach to this in Playframewrk v2.1 Ho un backport of the fix on the 2.0.x branch

Fino a quando non viene fusa e rilasciato, è qui cosa ho fatto (funziona su Play 2.0.3+):

Ho definito il mio oggetto Helpers in un pacchetto libs come tale.

package libs 

import play.api.mvc._ 

import play.api.libs.iteratee._ 
import play.api.libs.concurrent._ 
import play.api.test._ 

object Helpers { 

    def routeAndCall[T](request: FakeRequest[T]): Option[Result] = { 
    routeAndCall(this.getClass.getClassLoader.loadClass("Routes").asInstanceOf[Class[play.core.Router.Routes]], request) 
    } 
    /** 
    * Use the Router to determine the Action to call for this request and executes it. 
    */ 
    def routeAndCall[T, ROUTER <: play.core.Router.Routes](router: Class[ROUTER], request: FakeRequest[T]): Option[play.api.mvc.Result] = { 
    val routes = router.getClassLoader.loadClass(router.getName + "$").getDeclaredField("MODULE$").get(null).asInstanceOf[play.core.Router.Routes] 
    routes.routes.lift(request).map { 
     case a: Action[_] => 
     val action = a.asInstanceOf[Action[T]] 
     val parsedBody: Option[Either[play.api.mvc.Result, T]] = action.parser(request).fold(
      (a, in) => Promise.pure(Some(a)), 
      k => Promise.pure(None), 
      (msg, in) => Promise.pure(None) 
     ).await.get 

     parsedBody.map{resultOrT => 
      resultOrT.right.toOption.map{innerBody => 
      action(FakeRequest(request.method, request.uri, request.headers, innerBody)) 
      }.getOrElse(resultOrT.left.get) 
     }.getOrElse(action(request)) 
    } 
    } 

} 

Poi, nel mio test ho importare i miei aiutanti e tutto il contesto Helpers gioco, tranne che per routeAndCall:

import libs.Helpers._ 
import play.api.test.Helpers.{routeAndCall => _,_} 

ho quindi utilizzare un giro a impostare il mio app (Ho bisogno di fornire un'applicazione. segreto i memorizzare il nome utente autenticato nella sessione che si basa su un cookie firmato)

def appWithSecret():Map[String,String]={ 
    Map(("application.secret","the answer is 42 !")) 
    } 


    object emptyApp extends Around { 
    def around[T <% Result](t: => T) = { 
     running(FakeApplication(additionalConfiguration = inMemoryMongoDatabase("emptyApp")++appWithSecret())) { 
     User(new ObjectId, "Jane Doe", "[email protected]", "id1").save() 
     t // execute t inside a http session 
     } 
    } 
    } 

Questo mi permette di scrivere le seguenti prove:

"respond to the index Action" in emptyApp { 
     val request: FakeRequest[AnyContent] = FakeRequest(GET, "/expenses").withSession(("email", "[email protected]")) 
     val Some(result) = routeAndCall(request) 

     status(result) must equalTo(OK) 
     contentType(result) must beSome("application/json") 
     charset(result) must beSome("utf-8") 
     contentAsString(result) must contain("Hello Bob") 
    } 

Consente di esercitare il codice protetto anche se non è un test di unità.

Problemi correlati