2012-04-01 34 views
5

我玩Play 2.0,Scala版本。目前,我分析了Zentasks sample app如何從Play 2.0測試Zentasks示例應用程序

此應用程序的一部分是身份驗證機制,主要涵蓋Secured特質。我想知道如何測試安全操作,例如。 indexProjects controller

對於未保護的動作,我可能會做這樣的事情

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

運行一個動作,並取得其結果。

如果採取安全措施,該怎麼辦?

免責聲明:我對Scala和Play都是全新的,所以所有提示都非常有價值。謝謝!

回答

1

好的,我也不是很好的專家,但這裏有一個想法。

創建一個trait InSecure trait extends Secured,它覆蓋安全操作並始終允許訪問。 然後,您可以在測試中創建一個object InSecureProjects extends Projects with InSecture,這應該只覆蓋安全檢查並讓您在沒有任何安全性的情況下測試這些操作。

現在,您不用在Projects上運行測試,而是在InSecureProjects上運行它們。您可以爲其他安全控制器執行完全相同的操作。

我沒有測試過,所以讓我知道,如果它的工作原理;)

2

有一個在Playframewrk V2.1一fix for the integrated approach to this我有一個backport of the fix on the 2.0.x branch

,直到它得到合併,發佈,這裏是我做了什麼(它適用於Play 2.0.3+):

我在libs軟件包中定義了我自己的Helpers對象,如下所示。

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 => _,_} 

然後我用了大約設置我的應用程序(我需要提供應用。祕密,因爲我存儲在會話驗證的用戶名是基於一個簽名的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 
     } 
    } 
    } 

這讓我寫了下面的測試:

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

它允許您行使安全代碼,即使它不是單元測試。

相關問題