zinking
zinking

Reputation: 5685

convert Iteratee to Result

I am writing test-cases for my play application controller, and I am having trouble getting the action result.

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

this would work only when the Action is specified parse.multipartFormData, if it is changed to parse.json

type mismatch; found : play.api.libs.iteratee.Iteratee[Array[Byte],play.api.mvc.SimpleResult] required: scala.concurrent.Future[play.api.mvc.SimpleResult]

I don't know why , so I changed to

val Some(jsonresult ) = route( request )

this time the compilation can pass, but my Authentication stub cannot pass anymore. what is causing that weird error ? and if work with route, why the cookie didn't work.

Upvotes: 5

Views: 978

Answers (2)

flurdy
flurdy

Reputation: 3972

tjdett's answer explains the issue in detail.

For a quick solution that may work in your instance simply run the iteratee result payload.

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

Upvotes: 1

tjdett
tjdett

Reputation: 1723

This problem arises because play.api.mvc.Action[A] contains these two apply methods:

// 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, so the A in this case makes all the difference. If it doesn't match the action, you'll call the wrong method.

If your action is a Action[AnyContent], then you must pass a Request[AnyContent] - Request[AnyContentAsJson] will work, but FakeRequest[JsValue] won't, because only the former is a Request[AnyContent].

When you use ActionBuilder with a BodyParser[A], you create an Action[A]. As a result, you'll need a Request[A] to test, which means that the type of data in your question is critically important.

  • parse.json returns a BodyParser[JsValue], so data must be a JsValue
  • parse.multipartFormData returns a BodyParser[MultipartFormData[TemporaryFile]], so data must be multi-part form data.

(Note: It's been a while since you asked this question, so I'm answering it using Play 2.3, rather than the 2.2 that you were using when it was asked.)

Upvotes: 6

Related Questions