玩 2.4:如何使用 MultipartFormData 编写文件上传测试用例

Posted

技术标签:

【中文标题】玩 2.4:如何使用 MultipartFormData 编写文件上传测试用例【英文标题】:Play 2.4: How to write a test case for file upload with 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 上传的文件?

【问题讨论】:

【参考方案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”。我猜它与***.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,这似乎是本期***.com/questions/32791562/…中的一个。

以上是关于玩 2.4:如何使用 MultipartFormData 编写文件上传测试用例的主要内容,如果未能解决你的问题,请参考以下文章

玩2.4 Ebean分页问题

玩 1.2.4 自动提交

单身人士玩啥! Framework 2.4 提供开箱即用?

玩 2.4 参数化代数数据类型 JSON 验证

如何使用Slick和Play在测试中应用手动演变! 2.4

玩 2.4 表单字段值绑定到 java.time.LocalDate 类型