Dropwizard DropwizardAppRule测试多部分文件上传

huangapple go评论76阅读模式
英文:

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);
    }
}

我得到了以下错误:

找不到适用于介质类型为 multipart/form-data、类型为类 org.glassfish.jersey.media.multipart.FormDataMultiPart、泛型类型为类 org.glassfish.jersey.media.multipart.FormDataMultiPart 的 MessageBodyWriter。
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: 找不到适用于介质类型为 multipart/form-data、类型为类 org.glassfish.jersey.media.multipart.FormDataMultiPart、泛型类型为类 org.glassfish.jersey.media.multipart.FormDataMultiPart 的 MessageBodyWriter。

请注意,在应用程序引导中有必要注册 multipart:

private List<Resource> configureJersey(Configuration config, Environment environment) {
    // 添加一些必需的功能
    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);
}

就像你建议的那样。

英文:

I'm currently trying to write an IT test by calling a resource that takes MultiPartFormData as input.

It work when the application starts "normaly" but doesn't when started with DropwizardAppRule helper.

Here is my code :

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

    var file = new File(&quot;src/test/resources/import/products&amp;offers.csv&quot;);
    var fileDataBodyPart = new FileDataBodyPart(&quot;file&quot;, 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(&quot;http://localhost:%d/ui/shop-inputs/csv/%s&quot;, 8082, shopId))
                            .queryParam(&quot;importContentType&quot;, &quot;BOTH&quot;)
                            .request()
                            .headers(multipartHeaders)
                            .post(Entity.entity(multiPart, multiPart.getMediaType()));

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

QORUS_APP is intanciated like so :

public abstract class AbstractRestResourceTest {

    @ClassRule
    public static final DropwizardAppRule&lt;Configuration&gt; QORUS_APP = ResourceSuite.QORUS_APP;
    private static final String USER_API_KEY = &quot;authenticatedUserApiKey&quot;;

    protected static MultivaluedMap&lt;String, Object&gt; headers;

    public AbstractRestResourceTest() {
        headers = new MultivaluedHashMap&lt;&gt;();
        headers.putSingle(&quot;Content-Type&quot;, &quot;application/json&quot;);
        headers.putSingle(&quot;Accept&quot;, &quot;*/*&quot;);
        headers.putSingle(NgTokenAuthFilter.AUTHORIZATION_HEADER, &quot;Bearer &quot; + USER_API_KEY);
    }
}

I get the following error :

> 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.

Note that there is the required registering of multipart in Application bootstrap :

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

UPDATE:

Thanks @paul-samsotha for taking time to answer.

I did the following:

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

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

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

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

Just like you suggest.

答案1

得分: 1

错误发生在客户端在发送请求之前。查看关于表单的文档,它会告诉你在客户端也需要注册 MultiPartFeature。你可以通过 Client 或者 WebTarget 进行注册。Dropwizard 建议你在 WebTarget 中进行注册,就像示例中所示。

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

The error is occurring on the client side before it sends out the request. See the docs on Forms, it will show you that you need to register the MultiPartFeature on the client side also. You can register it either with the Client or the WebTarget. Dropwizard suggests you register it with the WebTarget, as shown in the example.

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

huangapple
  • 本文由 发表于 2020年10月8日 17:15:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/64259388.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定