Dropwizard DropwizardAppRule 测试多部分文件上传

Dropwizard DropwizardAppRule test multipart file upload

我目前正在尝试通过调用将 MultiPartFormData 作为输入的资源来编写 IT 测试。

它在应用程序“正常”启动时有效,但在使用 DropwizardAppRule 助手启动时无效。

这是我的代码:

@Test
public void importProductAndOfferCsvShopInput() {
    // Given
    var shopId = "id";
    var multipartHeaders = headers;
    multipartHeaders.putSingle("Content-Type", "multipart/form-data");

    var file = new File("src/test/resources/import/products&offers.csv");
    var fileDataBodyPart = new FileDataBodyPart("file", file, MediaType.APPLICATION_OCTET_STREAM_TYPE);
    MultiPart multiPart = new FormDataMultiPart().bodyPart(fileDataBodyPart, MediaType.MULTIPART_FORM_DATA_TYPE);

    // When
    var response = QORUS_APP.client().target(String.format("http://localhost:%d/ui/shop-inputs/csv/%s", 8082, shopId))
                            .queryParam("importContentType", "BOTH")
                            .request()
                            .headers(multipartHeaders)
                            .post(Entity.entity(multiPart, multiPart.getMediaType()));

    // Then
    assertThat(response.getStatusInfo()).isEqualTo(Response.Status.OK);
}

QORUS_APP 是这样的:

public abstract class AbstractRestResourceTest {

    @ClassRule
    public static final DropwizardAppRule<Configuration> QORUS_APP = ResourceSuite.QORUS_APP;
    private static final String USER_API_KEY = "authenticatedUserApiKey";

    protected static MultivaluedMap<String, Object> headers;

    public AbstractRestResourceTest() {
        headers = new MultivaluedHashMap<>();
        headers.putSingle("Content-Type", "application/json");
        headers.putSingle("Accept", "*/*");
        headers.putSingle(NgTokenAuthFilter.AUTHORIZATION_HEADER, "Bearer " + USER_API_KEY);
    }
}

我收到以下错误:

MessageBodyWriter not found for media type=multipart/form-data, type=class org.glassfish.jersey.media.multipart.FormDataMultiPart, genericType=class org.glassfish.jersey.media.multipart.FormDataMultiPart. org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=multipart/form-data, type=class org.glassfish.jersey.media.multipart.FormDataMultiPart, genericType=class org.glassfish.jersey.media.multipart.FormDataMultiPart.

注意需要在Application中注册multipart bootstrap :

    private List<Resource> configureJersey(Configuration config, Environment environment) {
    // adds some required features
    environment.jersey().register(MultiPartFeature.class);

更新:

感谢@paul-samsotha 花时间回答。

我做了以下事情:

@Test
public void importProductAndOfferCsvShopInput() {
    // Given
    var shopId = "5b03ebe9c9aa0423b4a73dce";
    var multipartHeaders = headers;
    multipartHeaders.putSingle("Content-Type", "multipart/form-data");

    var file = new File("src/test/resources/import/products&offers.csv");
    var fileDataBodyPart = new FileDataBodyPart("file", file);
    var multiPart = new FormDataMultiPart().bodyPart(fileDataBodyPart);

    // When
    var response = QORUS_APP.client()
                            .target(String.format("http://localhost:%d/ui/shop-inputs/csv/%s", 8082, shopId))
                            .register(MultiPartFeature.class)
                            .queryParam("importContentType", "BOTH")
                            .request()
                            .headers(multipartHeaders)
                            .post(Entity.entity(multiPart, multiPart.getMediaType()));

    // Then
    assertThat(response.getStatusInfo()).isEqualTo(Response.Status.OK);
}

就像你建议的那样。

客户端在发送请求之前发生错误。 See the docs on Forms,它会告诉你你还需要在客户端注册 MultiPartFeature。您可以使用 ClientWebTarget 注册它。 Dropwizard 建议您使用 WebTarget 注册它,如示例中所示。

var response = QORUS_APP.client()
        .target(...)
        .register(MultiPartFeature.class)
        ...