我想编写一个单元测试来测试我的自定义操作构建器。
一旦我在我的测试中将ActionWithSession设置为实例,我如何实例化它就像在控制器中一样?
如果重定向或返回会话,我如何测试边缘情况?
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
}
}
答案 0 :(得分:3)
如果你正在使用Play 2.3,你应该能够利用PlaySpecification
特征,它提供call
方法来测试动作。看一下Documentation,特别是关于"单元测试EssentialAction的部分
"
这是一个基于您发布的代码的人为的最小示例。它基本上只是检查请求头是否包含" 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
}
}
}