2012-04-01 11 views
5

Gram w wersji Play 2.0, Scala. Obecnie analizuję Zentasks sample app.Jak przetestować przykładową aplikację Zentasks od Play 2.0

Jedną z części tej aplikacji jest mechanizm uwierzytelniania w większości objęty cechą Secured. Zastanawiam się, jak mogę przetestować zabezpieczone działania, np. index z Projects controller.

Dla nie-zabezpieczonej działania, prawdopodobnie coś zrobić jak

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

uruchomić akcję i uzyskać jego wynik.

Co należy zrobić w przypadku zabezpieczonego działania?

Nota prawna: Jestem całkowicie nowy w Scali i Play, więc wszystkie wskazówki są bardzo cenne. Dzięki!

Odpowiedz

1

OK, nie jestem też świetnym ekspertem, ale tutaj jest pomysł.

Utwórz trait InSecure trait extends Secured, który zastępuje zabezpieczone działania i zawsze umożliwia dostęp. W teście można wykonać test object InSecureProjects extends Projects with InSecture, co powinno przesłonić jedynie kontrole bezpieczeństwa i pozwolić na przetestowanie działań bez żadnych zabezpieczeń.

Teraz, zamiast uruchamiać testy na Projects, uruchamiasz je na InSecureProjects. Możesz zrobić dokładnie to samo dla innych zabezpieczonych kontrolerów.

ja jej nie testowane, więc daj mi znać, jeśli to działa;)

2

Jest fix for the integrated approach to this w Playframewrk v2.1 Mam backport of the fix on the 2.0.x branch

Dopóki nie zostanie połączone i zwolniony, tu jest co zrobiłem (działa w wersji Play 2.0.3+):

Zdefiniowałem swój własny obiekt Pomocników w pakiecie libs, tak jak.

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)) 
    } 
    } 

} 

Wtedy w moim teście mogę importować moich pomocników i cały kontekst Pomocnicy Play, z wyjątkiem routeAndCall:

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

I wtedy użyć Około ustawienia mojego app (muszę dostarczyć aplikację. sekret jak przechowywać uwierzytelnioną nazwę użytkownika w sesji, która opiera się na podpisanym cookie)

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 
     } 
    } 
    } 

To pozwala mi napisać następujące badania:

"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") 
    } 

Umożliwia korzystanie z zabezpieczonego kodu, mimo że nie jest to test jednostkowy.

Powiązane problemy