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
。您可以使用 Client
或 WebTarget
注册它。 Dropwizard 建议您使用 WebTarget
注册它,如示例中所示。
var response = QORUS_APP.client()
.target(...)
.register(MultiPartFeature.class)
...
我目前正在尝试通过调用将 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
。您可以使用 Client
或 WebTarget
注册它。 Dropwizard 建议您使用 WebTarget
注册它,如示例中所示。
var response = QORUS_APP.client()
.target(...)
.register(MultiPartFeature.class)
...