RequestBuilder的bodyMultipart()方法有问题吗?

时间:2017-03-02 14:49:31

标签: java playframework

我正在使用play 2.5.3,但我也尝试过2.5.4和2.5.12,并且都有相同的问题。

我想在请求中使用多部分表单体对我的控制器进行单元测试。这是我的代码:

import com.fasterxml.jackson.databind.node.ObjectNode;
import controllers.payment.application.PaymentApplicationController;
import facade.PaymentApplicationFacade;
import it.innove.play.pdf.PdfGenerator;
import org.junit.Before;
import org.junit.Test;
import play.Application;
import play.inject.guice.GuiceApplicationBuilder;
import play.libs.Json;
import play.mvc.Http.MultipartFormData;
import play.mvc.Http.RequestBuilder;
import play.mvc.Result;
import play.test.WithApplication;

import java.util.Arrays;
import java.util.HashMap;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static play.mvc.Http.Status.OK;
import static play.test.Helpers.*;

@Test
public void testSubmit() {

    MultipartFormData.DataPart dp = new MultipartFormData.DataPart("FirstName", "test");

    RequestBuilder requestBuilder = fakeRequest().bodyMultipart(Arrays.asList(dp), mat);

    Result result = invokeWithContext(requestBuilder, ()->new PaymentApplicationController(paymentApplicationFacade, pdfGenerator).submit());
    assertEquals(OK, result.status());
    assertEquals("text/html", result.contentType().get());
    assertEquals("utf-8", result.charset().get());
    assertTrue(contentAsString(result).contains("Welcome"));
}

似乎bodyMultipart()方法始终使用RawBuffer类型的正文创建请求。我检查了RequestBuilder代码:

public RequestBuilder bodyMultipart(List<MultipartFormData.Part<Source<ByteString, ?>>> data, Materializer mat) {
    String boundary = MultipartFormatter.randomBoundary();
    try {
        ByteString materializedData = MultipartFormatter
                .transform(Source.from(data), boundary)
                .runWith(Sink.reduce(ByteString::concat), mat)
                .toCompletableFuture()
                .get();

        play.api.mvc.RawBuffer buffer = new play.api.mvc.RawBuffer(materializedData.size(), materializedData);
        return body(new RequestBody(JavaParsers.toJavaRaw(buffer)), MultipartFormatter.boundaryToContentType(boundary));
    } catch (InterruptedException | ExecutionException e) {
        throw new RuntimeException("Failure while materializing Multipart/Form Data");
    }
}

它看起来确实如此。这导致我的控制器执行:

MultipartFormData body = request().body().asMultipartFormData();

它只返回null

有人可以提供帮助吗?

1 个答案:

答案 0 :(得分:0)

使用我的RequestBuilder和MultipartFormData包装暂时绕过这个,但仍然需要一个优雅的解决方案。

在测试中:

RequestBuilder requestBuilder = fakeRequest();

MyRequestBuilder myRequestBuilder = new MyRequestBuilder(requestBuilder);
myRequestBuilder.setBody(new Http.RequestBody(myMultipartFormData), "multipart/form-data");

Result result = invokeWithContext(myRequestBuilder, ()->new PaymentApplicationController(paymentApplicationFacade, pdfGenerator).submit());

MyRequestBuilder类:

import play.mvc.Http.RequestBody;
import play.mvc.Http.RequestBuilder;

/**
 * Created by yongmu on 3/2/17.
 */
public class MyRequestBuilder extends RequestBuilder {
    RequestBuilder requestBuilder;

    public MyRequestBuilder(RequestBuilder requestBuilder) {
        this.requestBuilder = requestBuilder;
    }

    public void setBody(RequestBody body, String contentType) {
        super.body(body, contentType);
    }
}

MyMultipartFormData类:

import play.mvc.Http.*;

import java.util.List;
import java.util.Map;

/**
 * Created by yongmu on 3/2/17.
 */
public class MyMultipartFormData<A> extends MultipartFormData<A> {
    Map<String, String> form;

    public MyMultipartFormData(Map<String, String> form) {
        this.form = form;
    }

    public Map<String, String[]> asFormUrlEncoded() {
        return null;
    }

    /**
     * Retrieves all file parts.
     *
     * @return the file parts
     */
    public List<FilePart<A>> getFiles() {
        return null;
    }
}