Scala 如何测试扩展ActionBuilder的自定义操作?

Scala 如何测试扩展ActionBuilder的自定义操作?,scala,playframework,Scala,Playframework,我想写一个单元测试来测试我的自定义动作生成器 一旦我在测试中将ActionWithSession设置为in-instance,我如何像在控制器中一样实例化它 我如何测试边缘情况,如果它重定向或返回会话 class SessionAwareRequest[A](val context: MyContext, request: Request[A]) extends WrappedRequest[A](request) class ActionWithSession @Inject()(siteC

我想写一个单元测试来测试我的自定义动作生成器

一旦我在测试中将ActionWithSession设置为in-instance,我如何像在控制器中一样实例化它

我如何测试边缘情况,如果它重定向或返回会话

class SessionAwareRequest[A](val context: MyContext, request: Request[A]) extends WrappedRequest[A](request)

class ActionWithSession @Inject()(siteConfig: SiteConfig, userService: UserService)
  extends ActionBuilder[SessionAwareRequest] {

  def invokeBlock[A](request: Request[A], block: (SessionAwareRequest[A]) => Future[Result]) = {
    val session = loadSession(request)

    if(session.isDefined) {
      val result: Future[Result] = block(new SessionAwareRequest(session.get, request))
      result.map(_.withCookies(CookieHelper.newSession(session.get)(request)))
    }
    else {
      Future.successful(Results.Redirect(routes.MessagesController.show("error!"))) 

  }

  def loadSession(requestHeader: RequestHeader): Option[MySession] = {
    ...
      Some(MySession(...))
    else
      None
  }

}

如果您正在使用Play 2.3,您应该能够利用
Play规范
特性,它提供了一个
调用
方法来测试动作。请看一下,特别是关于“单元测试的重要性”一节 “

下面是一个基于您发布的代码的人工示例。它基本上只是检查请求头是否包含“foo”字段,如果是,则返回OK以及通过自定义动作生成器添加的附加cookie“baz”。如果“foo”头丢失,它将返回BadRequest。希望能有帮助

import play.api.mvc._
import play.api.test.{FakeRequest, PlaySpecification}
import scala.concurrent.Future

class ActionSpec extends PlaySpecification {
  case class MySession()

  class SessionAwareRequest[A](val context: MySession, request: Request[A]) extends WrappedRequest[A](request)

  object ActionWithSession extends ActionBuilder[SessionAwareRequest] {

    def loadSession(requestHeader: RequestHeader): Option[MySession] = {
      if (requestHeader.headers.get("foo").isDefined)
        Some(MySession())
      else
        None
    }

    def invokeBlock[A](request: Request[A], block: (SessionAwareRequest[A]) => Future[Result]): Future[Result] = {
      val session = loadSession(request)

      if (session.isDefined) {
        val result: Future[Result] = block(new SessionAwareRequest(session.get, request))
        result.map(_.withCookies(Cookie("baz", "quux")))
      } else {
        Future.successful(Results.BadRequest)
      }
    }
  }

  "My custom action" should {

    "return HTTP code 400 in case the request header does not contain a 'foo' field" in {
      val foo = call(ActionWithSession { request =>
        Results.Ok("Yikes")
      }, FakeRequest())
      status(of = foo) must beEqualTo(BAD_REQUEST)
      cookies(of = foo).get("baz") must beNone
    }

    "return HTTP code 200 in case the request header does contain a 'foo' field" in {
      val foo = call(ActionWithSession { request =>
        Results.Ok("Yikes")
      }, FakeRequest().withHeaders("foo" -> "bar"))
      status(of = foo) must beEqualTo(OK)
      cookies(of = foo).get("baz") must beSome
    }
  }

}

如果您正在使用Play 2.3,您应该能够利用
Play规范
特性,它提供了一个
调用
方法来测试动作。请看一下,特别是关于“单元测试的重要性”一节 “

下面是一个基于您发布的代码的人工示例。它基本上只是检查请求头是否包含“foo”字段,如果是,则返回OK以及通过自定义动作生成器添加的附加cookie“baz”。如果“foo”头丢失,它将返回BadRequest。希望能有帮助

import play.api.mvc._
import play.api.test.{FakeRequest, PlaySpecification}
import scala.concurrent.Future

class ActionSpec extends PlaySpecification {
  case class MySession()

  class SessionAwareRequest[A](val context: MySession, request: Request[A]) extends WrappedRequest[A](request)

  object ActionWithSession extends ActionBuilder[SessionAwareRequest] {

    def loadSession(requestHeader: RequestHeader): Option[MySession] = {
      if (requestHeader.headers.get("foo").isDefined)
        Some(MySession())
      else
        None
    }

    def invokeBlock[A](request: Request[A], block: (SessionAwareRequest[A]) => Future[Result]): Future[Result] = {
      val session = loadSession(request)

      if (session.isDefined) {
        val result: Future[Result] = block(new SessionAwareRequest(session.get, request))
        result.map(_.withCookies(Cookie("baz", "quux")))
      } else {
        Future.successful(Results.BadRequest)
      }
    }
  }

  "My custom action" should {

    "return HTTP code 400 in case the request header does not contain a 'foo' field" in {
      val foo = call(ActionWithSession { request =>
        Results.Ok("Yikes")
      }, FakeRequest())
      status(of = foo) must beEqualTo(BAD_REQUEST)
      cookies(of = foo).get("baz") must beNone
    }

    "return HTTP code 200 in case the request header does contain a 'foo' field" in {
      val foo = call(ActionWithSession { request =>
        Results.Ok("Yikes")
      }, FakeRequest().withHeaders("foo" -> "bar"))
      status(of = foo) must beEqualTo(OK)
      cookies(of = foo).get("baz") must beSome
    }
  }

}

如果您正在使用Play 2.3,您应该能够利用
Play规范
特性,它提供了一个
调用
方法来测试动作。请看一下,特别是关于“单元测试的重要性”一节 “

下面是一个基于您发布的代码的人工示例。它基本上只是检查请求头是否包含“foo”字段,如果是,则返回OK以及通过自定义动作生成器添加的附加cookie“baz”。如果“foo”头丢失,它将返回BadRequest。希望能有帮助

import play.api.mvc._
import play.api.test.{FakeRequest, PlaySpecification}
import scala.concurrent.Future

class ActionSpec extends PlaySpecification {
  case class MySession()

  class SessionAwareRequest[A](val context: MySession, request: Request[A]) extends WrappedRequest[A](request)

  object ActionWithSession extends ActionBuilder[SessionAwareRequest] {

    def loadSession(requestHeader: RequestHeader): Option[MySession] = {
      if (requestHeader.headers.get("foo").isDefined)
        Some(MySession())
      else
        None
    }

    def invokeBlock[A](request: Request[A], block: (SessionAwareRequest[A]) => Future[Result]): Future[Result] = {
      val session = loadSession(request)

      if (session.isDefined) {
        val result: Future[Result] = block(new SessionAwareRequest(session.get, request))
        result.map(_.withCookies(Cookie("baz", "quux")))
      } else {
        Future.successful(Results.BadRequest)
      }
    }
  }

  "My custom action" should {

    "return HTTP code 400 in case the request header does not contain a 'foo' field" in {
      val foo = call(ActionWithSession { request =>
        Results.Ok("Yikes")
      }, FakeRequest())
      status(of = foo) must beEqualTo(BAD_REQUEST)
      cookies(of = foo).get("baz") must beNone
    }

    "return HTTP code 200 in case the request header does contain a 'foo' field" in {
      val foo = call(ActionWithSession { request =>
        Results.Ok("Yikes")
      }, FakeRequest().withHeaders("foo" -> "bar"))
      status(of = foo) must beEqualTo(OK)
      cookies(of = foo).get("baz") must beSome
    }
  }

}

如果您正在使用Play 2.3,您应该能够利用
Play规范
特性,它提供了一个
调用
方法来测试动作。请看一下,特别是关于“单元测试的重要性”一节 “

下面是一个基于您发布的代码的人工示例。它基本上只是检查请求头是否包含“foo”字段,如果是,则返回OK以及通过自定义动作生成器添加的附加cookie“baz”。如果“foo”头丢失,它将返回BadRequest。希望能有帮助

import play.api.mvc._
import play.api.test.{FakeRequest, PlaySpecification}
import scala.concurrent.Future

class ActionSpec extends PlaySpecification {
  case class MySession()

  class SessionAwareRequest[A](val context: MySession, request: Request[A]) extends WrappedRequest[A](request)

  object ActionWithSession extends ActionBuilder[SessionAwareRequest] {

    def loadSession(requestHeader: RequestHeader): Option[MySession] = {
      if (requestHeader.headers.get("foo").isDefined)
        Some(MySession())
      else
        None
    }

    def invokeBlock[A](request: Request[A], block: (SessionAwareRequest[A]) => Future[Result]): Future[Result] = {
      val session = loadSession(request)

      if (session.isDefined) {
        val result: Future[Result] = block(new SessionAwareRequest(session.get, request))
        result.map(_.withCookies(Cookie("baz", "quux")))
      } else {
        Future.successful(Results.BadRequest)
      }
    }
  }

  "My custom action" should {

    "return HTTP code 400 in case the request header does not contain a 'foo' field" in {
      val foo = call(ActionWithSession { request =>
        Results.Ok("Yikes")
      }, FakeRequest())
      status(of = foo) must beEqualTo(BAD_REQUEST)
      cookies(of = foo).get("baz") must beNone
    }

    "return HTTP code 200 in case the request header does contain a 'foo' field" in {
      val foo = call(ActionWithSession { request =>
        Results.Ok("Yikes")
      }, FakeRequest().withHeaders("foo" -> "bar"))
      status(of = foo) must beEqualTo(OK)
      cookies(of = foo).get("baz") must beSome
    }
  }

}