Play2 でファイルアップロードをテストする

Play2.0 の FakeRequest って withFormUrlEncodedBody はあるけど withMultipartFormDataBody はありません。
ですが、FakeRequest[MultipartFormData[TemporaryFile] ] を地道に作ってあげれば大丈夫。*1


こんな感じになります。

package controllers

import java.io.File
import play.api.libs.Files
import play.api.libs.Files.TemporaryFile
import play.api.mvc._
import play.api.mvc.MultipartFormData._
import play.api.test._
import play.api.test.Helpers._
import org.scalatest.FunSuite
import org.scalatest.matchers.ShouldMatchers

class ApplicationSuite extends FunSuite with ShouldMatchers {

  test("file upload") {
    running (FakeApplication()) {
      val key = "image"
      val contentType = Some("images/png")
      val testImageFile = new File("test/resources/testimage.png")
      val tmpfile = File.createTempFile("xxx", "xxx")
      Files.copyFile(testImageFile, tmpfile)
      val ref = TemporaryFile(tmpfile)
      val files = Seq(FilePart(key, "testimage.png", contentType, ref))
      val multiPartFormData = MultipartFormData(Map("filename" -> Seq("foo")), files, Seq(), Seq())
      val fakeRequest = FakeRequest("", "", FakeHeaders(), multiPartFormData)
      val result = controllers.Application.upload(fakeRequest)
      status(result) should be (OK)
      contentAsString(result) should include ("Success: file=testimage.png, size=6482, filename: foo")
    }
  }

}


アップロードしてるファイルを一旦一時ファイルにコピーしている理由ですが、直接テストデータの画像ファイルを play.api.libs.Files.TemporaryFile に渡すと、使い終わったあと消されちゃって、2回目以降テストが失敗してしまうからです。

*1:] ] とスペース空けてるのははてな記法があらぶるからです