将Iteratee转换为Result

时间:2014-04-26 13:46:38

标签: scala playframework

我正在为我的播放应用程序控制器编写测试用例,但我无法获得操作结果。

val jsonresult = UserController.importOPML()( 
   FakeRequest(POST, "/user/import-opml",FakeHeaders(),data)
   .withCookies(cookie) 
)

只有在指定了动作parse.multipartFormData时才会有效,如果它已更改为parse.json

  

类型不匹配;发现:play.api.libs.iteratee.Iteratee [Array [Byte],play.api.mvc.SimpleResult]需要:        scala.concurrent.Future [play.api.mvc.SimpleResult]

我不知道为什么,所以我改为

val Some(jsonresult ) = route( request )

这次编译可以通过,但我的身份验证存根不能再通过了。造成这种奇怪错误的原因是什么?如果与路线一起工作,为什么cookie没有用。

2 个答案:

答案 0 :(得分:6)

出现此问题是因为play.api.mvc.Action[A]包含以下两种应用方法:

// What you're hoping for
def apply(request: Request[A]): Future[Result]

// What actually gets called
def apply(rh: RequestHeader): Iteratee[Array[Byte], Result]

Request[A] extends RequestHeader,因此在这种情况下A会产生重大影响。如果它与操作不匹配,您将调用错误的方法。

如果您的操作是Action[AnyContent],那么您必须通过Request[AnyContent] - Request[AnyContentAsJson]才会有效,但FakeRequest[JsValue]不会,因为只有前者是{ {1}}。

Request[AnyContent]ActionBuilder一起使用后,您可以创建BodyParser[A]。因此,您需要Action[A]进行测试,这意味着您问题中Request[A]的类型非常重要。

  • data返回parse.json,因此BodyParser[JsValue]必须是data
  • JsValue会返回parse.multipartFormData,因此BodyParser[MultipartFormData[TemporaryFile]]必须是多部分表单数据。

(注意:自从你提出这个问题以来已经有一段时间了,所以我用Play 2.3回答它,而不是在你被问到时使用的2.2。)

答案 1 :(得分:1)

tjdett的回答详细解释了这个问题。

对于可能在您的实例中起作用的快速解决方案,只需run迭代结果有效负载。

val jsonresult = UserController.importOPML()( 
   FakeRequest(POST, "/user/import-opml",FakeHeaders(),data)
   .withCookies(cookie) 
).run