【问题标题】:Play2 testing controller methods using Action compositionPlay2 使用 Action 组合测试控制器方法
【发布时间】:2015-02-05 12:53:37
【问题描述】:

我想使用动作组合来测试控制器动作。 下面是组合操作及其测试代码的示例。

安全特性:

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

后者需要 Request[Action[AnyContent], AnyContent] 但 FakeRequest 返回一个 Request[AnyContent]

关于如何创建适当类型的虚假请求的任何指示?

【问题讨论】:

    标签: unit-testing scala playframework-2.0


    【解决方案1】:

    这是我必须做的测试安全操作

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

    但这不适用于 Play 2.1,类型已更改...

    更新: 在 Play 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"
      }
    

    更新:这是我前段时间写的一篇相关博文 http://www.daodecode.com/blog/2013/03/08/testing-security-dot-authenticated-in-play-2-dot-0-and-2-dot-1/

    【讨论】:

      【解决方案2】:

      您是否尝试过使用 routeAndCall 方法?

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

      您可以使用 asFormUrlEncodedBody 方法在请求中添加您需要的任何参数和/或使用 withSession 方法向会话添加内容。

      【讨论】:

      • 还没有尝试过,但不明白为什么它不起作用。尽管我想专门对一种方法进行单元测试,但没有例如涉及路由,但我想现在更实用的方法是使用 routeAndCall。
      • 问题是,我认为 Request 和 FakeRequest 以不同的方式工作,你无法以你想要的方式解决这个问题。我不能发誓它是如此,所以不要引用我的话;)这个 git 项目还帮助我解决了我在 play 和 scala 中遇到的其他身份验证测试问题:github.com/maffoo/play-test-security
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-12
      • 2012-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多