2012-11-13 85 views
1

我想使用動作組合測試控制器動作。 下面是組合動作及其測試代碼的示例。Play2測試控制器方法使用動作組合

擔保性狀:

trait Secured { 
    def username(request: RequestHeader) = request.session.get(Security.username) 
    def onUnauthorized(request: RequestHeader) = Results.Redirect(routes.Auth.login) 

    def withAuth(f: => String => Request[AnyContent] => Result) = { 
     Security.Authenticated(username, onUnauthorized) { user => 
     Action(request => f(user)(request)) 
    } 
} 

控制器:

MyController extends Contrller with Secured { 
    def simple = Action { Ok("ok") } 
    def simpleWithauth = withAuth { implicit username => implicit request=> Ok("ok") } 
} 

測試代碼:

// This work fine 
val result1 = controller.simple()(FakeRequest()) 

// This wont compile 
val result2 = controller.simpleWithAuth()(FakeRequest()) 

後者將需要請求[操作[AnyContent],AnyContent ] 但FakeRequest返回請求[AnyContent]

任何關於如何創建適當類型的假請求的指針?

回答

3

這是我必須做測試保護的動作

def wrappedActionResult[A](wrapped: Action[(Action[A], A)], request: Request[A]): Result = wrapped.parser(request).run.await.get match { 
    case Left(errorResult) => errorResult 
    case Right((innerAction, _)) => innerAction(request) 
} 

和測試

running(app) { 
     val result = wrappedActionResult(FakeController().securedAction, invalidRequest) 
     status(result) must_== UNAUTHORIZED 
     contentAsString(result) must_== "must be authenticated" 
    } 

,這不符合遊戲2.1的工作,雖然,類型已經更改...

UPDATE: 在播放2.1那就更簡單了

我添加一些糖

implicit class ActionExecutor(action: EssentialAction) { 
    def process[A](request: Request[A]): Result = concurrent.Await.result(action(request).run, Duration(1, "sec")) 
} 

和測試現在看起來是這樣

running(app) { 
    val result = FakeController().securedAction process invalidRequest 
    status(result) must_== UNAUTHORIZED 
    contentAsString(result) must_== "must be authenticated" 
    } 

UPDATE:這裏有一個相關的博客帖子我以前 http://www.daodecode.com/blog/2013/03/08/testing-security-dot-authenticated-in-play-2-dot-0-and-2-dot-1/

0

您是否嘗試過使用routeAndCall方法?

val Some(result) = routeAndCall(FakeRequest(POST, "/someRoute")) 

您可以添加與asFormUrlEncodedBody方法和/或添加的東西與withSession方法會話您的請求需要的任何參數。

+0

避風港的某個時候寫了」 t試過但尚未明白爲什麼它不起作用。儘管我想專門測試一種方法而沒有例如涉及路由,但我想現在更實用的方法是使用routeAndCall。 – kerebus

+0

問題是,我認爲Request和FakeRequest以不同的方式工作,並且你無法以你想要的方式避開它。我不能發誓,它是如此,所以不要引用我;)這個git項目也幫助我一些其他認證測試問題,我玩和scala:https://github.com/maffoo/play-test-security – Jakob