【问题标题】:Play 2.4: How to write a test case for file upload with MultipartFormData玩 2.4:如何使用 MultipartFormData 编写文件上传测试用例
【发布时间】:2015-11-27 18:11:10
【问题描述】:

到目前为止(直到 Play 2.3)创建一个模拟请求,我使用了Helpers.fakeRequest().withAnyContent()。例如

private Request getMultiPartFormDataRequestForFileUpload(File file,
        String filePartKey, String contentType) {
    FilePart<TemporaryFile> part = new MultipartFormData.FilePart<>(
            filePartKey, file.getName(), Scala.Option(contentType),
            new TemporaryFile(file));
    List<FilePart<TemporaryFile>> fileParts = new ArrayList<>();
    fileParts.add(part);
    scala.collection.immutable.List<FilePart<TemporaryFile>> files = scala.collection.JavaConversions
            .asScalaBuffer(fileParts).toList();
    MultipartFormData<TemporaryFile> formData = new MultipartFormData<TemporaryFile>(
            null, files, null, null);
    return Helpers.fakeRequest().withAnyContent(formData);
}

在 Play 2.4 中,这不再可能了。如果我查看RequestBuilder(由 FakeRequest 实现)的来源,存在类似的功能,但它受到保护,我无法使用它。

protected Http.RequestBuilder   body(play.api.mvc.AnyContent anyContent)
Set a AnyContent to this request.

有谁知道我如何编写测试用例来检查在 2.4 中使用 MultipartFormData 上传的文件?

【问题讨论】:

    标签: java playframework playframework-2.4


    【解决方案1】:

    由于 Helpers.fakeRequest 是一个非常非常简单的方法(取自 github)

    /**
     * Build a new GET / fake request.
     */
    public static RequestBuilder fakeRequest() {
        return fakeRequest("GET", "/");
    }
    
    /**
     * Build a new fake request.
     */
    public static RequestBuilder fakeRequest(String method, String uri) {
        return new RequestBuilder().method(method).uri(uri);
    }
    

    您可以扩展 Http.RequestBuilder 从而访问受保护的方法:

    public class FakeRequestBuilder extends HttpRequestBuilder() {
       public RequestBuilder setAnyBody(RequestBody body, String contentType) {
         header("Content-Type", contentType);
         body(body);
       }
    }
    

    并在你的测试中使用它:

     //OLD return Helpers.fakeRequest().withAnyContent(formData);
     //NEW
     return new FakeRequestBuilder().setAnyBody(formData, "multipart/form-data").build(); 
     //or is it application/x-www-form-urlencoded for you?
    

    【讨论】:

    • 谢谢!我稍后再试。
    • 谢谢 Jan,但它不起作用。抱歉回复晚了(迟到总比没有好)。使用您的 FakeRequestBuilder,我会得到一个 scala.MatchError: AnyContentAsMultipartFormData。但我的内容类型是“应用程序/zip”。我猜它与stackoverflow.com/questions/32791562/…有关。
    【解决方案2】:

    在 Play2.4 中,body() 不接受 RequestBody,您必须先从 multipart 创建一个 AnyContent。示例:

    private class FakeRequestBuilder extends Http.RequestBuilder {
        public FakeRequestBuilder(String method, String uri) {
            method(method).uri(uri);
        }
    
        protected RequestBuilder setAnyBody(MultipartFormData<TemporaryFile> formData, String contentType) {
            header("Content-Type", contentType);
            AnyContent anyContent = new AnyContentAsMultipartFormData(formData);
            body(anyContent);
            return this;
        }
    }
    

    一个 MultiPartFormData 事物可以通过这个来创建,例如:

    private MultipartFormData<TemporaryFile> createFormData(String contentType, String filePartKey, File file) {
        FilePart<TemporaryFile> part = new MultipartFormData.FilePart<>(filePartKey, file.getName(), Scala.Option(contentType), new TemporaryFile(file));
        List<FilePart<TemporaryFile>> fileParts = new ArrayList<>();
        fileParts.add(part);
        scala.collection.immutable.List<FilePart<TemporaryFile>> files = scala.collection.JavaConversions.asScalaBuffer(fileParts).toList();
        MultipartFormData<TemporaryFile> formData = new MultipartFormData<TemporaryFile>(null, files, null, null);
        return formData;
    }
    

    【讨论】:

    • 感谢您的帮助。我试过你的解决方案。我还尝试使用 Mockito 模拟。我最终得到了一个scala.MatchError: AnyContentAsMultipartFormData,这似乎是本期stackoverflow.com/questions/32791562/…中的一个。
    猜你喜欢
    • 2022-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-27
    • 1970-01-01
    • 2013-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多