Writing a test case for file uploads in Play 2.1 and Scala

后端 未结 7 1943
猫巷女王i
猫巷女王i 2021-01-02 05:39

I found the following question/answer:

Test MultipartFormData in Play 2.0 FakeRequest

But it seems things have changed in Play 2.1. I\'ve tried adapting the

7条回答
  •  谎友^
    谎友^ (楼主)
    2021-01-02 06:11

    I managed to get this working with Play 2.1 based on various mailing list suggestions. Here's how I do it:

    import scala.language.implicitConversions
    
    import java.io.{ ByteArrayOutputStream, File }
    
    import org.apache.http.entity.mime.MultipartEntity
    import org.apache.http.entity.mime.content.{ ContentBody, FileBody }
    import org.specs2.mutable.Specification
    
    import play.api.http.Writeable
    import play.api.test.{ FakeApplication, FakeRequest }
    import play.api.test.Helpers._
    
    trait FakeMultipartUpload {
      case class WrappedFakeRequest[A](fr: FakeRequest[A]) {
        def withMultipart(parts: (String, ContentBody)*) = {
          // create a multipart form
          val entity = new MultipartEntity()
          parts.foreach { part =>
            entity.addPart(part._1, part._2)
          }
    
          // serialize the form
          val outputStream = new ByteArrayOutputStream
          entity.writeTo(outputStream)
          val bytes = outputStream.toByteArray
    
          // inject the form into our request
          val headerContentType = entity.getContentType.getValue
          fr.withBody(bytes).withHeaders(CONTENT_TYPE -> headerContentType)
        }
    
        def withFileUpload(fileParam: String, file: File, contentType: String) = {
          withMultipart(fileParam -> new FileBody(file, contentType))
        }
      }
    
      implicit def toWrappedFakeRequest[A](fr: FakeRequest[A]) = WrappedFakeRequest(fr)
    
      // override Play's equivalent Writeable so that the content-type header from the FakeRequest is used instead of application/octet-stream  
      implicit val wBytes: Writeable[Array[Byte]] = Writeable(identity, None)
    }
    
    class MyTest extends Specification with FakeMultipartUpload {
      "uploading" should {
        "be easier than this" in {
          running(FakeApplication()) {
            val uploadFile = new File("/tmp/file.txt")
            val req = FakeRequest(POST, "/upload/path").
              withFileUpload("image", uploadFile, "image/gif")
            val response = route(req).get
            status(response) must equalTo(OK)
          }
        }
      }
    }
    

提交回复
热议问题