2012-04-01 2 views
5

Play 2.0, 스칼라 버전에서 플레이합니다. 현재 Zentasks sample app을 분석합니다.Play 2.0에서 Zentasks 샘플 앱을 테스트하는 방법

이 응용 프로그램의 일부 중 하나는 대부분 Secured 특성으로 덮여있는 인증 메커니즘입니다. 나는 안전한 행동을 어떻게 테스트 할 수 있는지 궁금하다. . 하지 - 보안 조치를

, 나는 아마 작업을 실행하고 그 결과를 얻을 수

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

같은 것을 할 것입니다.

보안 조치가 취해진 경우 어떻게해야합니까?

면책 조항 : 저는 스칼라와 플레이 모두에 완전히 새로운 내용이므로 모든 힌트는 매우 가치가 있습니다. 감사!

답변

1

오케이, 나는 훌륭한 전문가도 아니지만 여기에 아이디어가 있습니다.

보안 조치를 무시하고 항상 액세스를 허용하는 trait InSecure trait extends Secured을 작성하십시오. 그러면 테스트에서 object InSecureProjects extends Projects with InSecture을 만들 수 있습니다. 이는 보안 검사를 무시하고 보안없이 작업을 테스트 할 수있게합니다.

이제 Projects에서 테스트를 실행하는 대신 InSecureProjects에서 테스트를 실행하십시오. 다른 보안 컨트롤러에 대해서도 똑같이 할 수 있습니다.

는 내가 그것을 테스트하지 않았습니다

, 그래서 작동하는지 알려주세요)

2

이 Playframewrk 2.1에서 fix for the integrated approach to this있다가 합병 발표 때까지 나는 여기하는 backport of the fix on the 2.0.x branch

이 내가 한 일 (Play 2.0.3 이상에서 작동) :

나는 내 자신의 헬퍼 객체를 libs 패키지에 정의했다.

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

} 

그런 다음 내 테스트에서 나는 routeAndCall를 제외하고, 내 도우미 전체 플레이 도우미 컨텍스트를 가져옵니다

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

나는 나는이 응용 프로그램을 제공해야합니다 (AN 주위 설정에 내 응용 프로그램을 사용합니다. 비밀 나는 서명 쿠키를 기반으로하는 세션에서 인증 된 사용자 이름)

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

이 날 다음 테스트를 작성할 수 있습니다 저장과 같이

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

단위 테스트가 아니더라도 보안 코드를 사용할 수 있습니다.

관련 문제