9

我们有一个REST服务,它接受包含该 hold的MultiPart POST请求。在 REST 服务中,可能会根据提供的数据创建一个文件。BodyPartsInputStream

任务

我们想要对基于其MultiPart输入执行文件操作的类进行单元测试。注意:我不想使用 Jersey-Test!Grizzly 不会加载我们需要将 DAO 和 fileHandler 服务注入到我们的 REST 服务类中的 spring 应用程序上下文。我们明确想要测试我们的 fileHandler 服务如何处理多部分数据。

然而,问题在于MultiPartREST 客户端发出的数据与REST 服务器接收的数据不同,因为球衣可能会对数据进行流式传输或其他操作。尝试测试(见下文)以下设置将导致

IllegalArgumentException [B cannot be cast to com.sun.jersey.multipart.BodyPartEntity

REST 客户端 - 发送 MultiPart

(只是片段,我省略了明显的东西):

    byte[] bytes = FileManager.readImageFileToArray(completePath, fileType);

    MultiPart multiPart = new MultiPart().
            bodyPart(new BodyPart(bytes, MediaType.APPLICATION_OCTET_STREAM_TYPE)).
            bodyPart(new BodyPart(fileName, MediaType.APPLICATION_XML_TYPE)).
            bodyPart(new BodyPart(senderId, MediaType.APPLICATION_XML_TYPE));

    ClientConfig cc = new DefaultClientConfig();
    cc.getClasses().add(MultiPartWriter.class);
    Client client = Client.create(cc);
    WebResource webResource = client.resource(requestUrl);
    Builder builder = webResource.type(MediaType.MULTIPART_FORM_DATA_TYPE);
    builder = addHeaderParams(builder, headerParams);

    ClientResponse response = builder.post(ClientResponse.class, multiPart);

服务器端 - 接收 MultiPart

休息:

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
@Transactional
public Response create(MultiPart multiPart) {

    try {
            multiPartReader.saveFile(multiPart);

服务器端 MultiPartReader 从多部分保存文件

public class MultiPartReader {

    public void saveFile(MultiPart multiPart) throws IOException {

        BodyPartEntity bpe = (BodyPartEntity) multiPart.getBodyParts().get(0).getEntity();
        InputStream inputStream = bpe.getInputStream();

        // ...

        BufferedImage bi = ImageIO.read(inputStream);
        String fileName = getFileNameFromMultiPart(multiPart);

        File file = new File(filename);

        if (file.isDirectory()) {
            ImageIO.write(bi, formatName, file);
        } else {
            file.mkdirs();
            ImageIO.write(bi, formatName, file);
        }

        bpe.close();
    }

测试 - 单独处理传入的 MultiPart

现在我想测试 MultiPartReader:

@Test
public void saveFile_should_Create_file() throws IOException {
    byte[] bytes = IOUtils.toByteArray(this.getClass().getResourceAsStream(fileResource));

    MultiPart multiPart = new MultiPart().
            bodyPart(new BodyPart(bytes, MediaType.APPLICATION_OCTET_STREAM_TYPE)).
            bodyPart(new BodyPart(fileName, MediaType.APPLICATION_XML_TYPE)).
            bodyPart(new BodyPart(senderId, MediaType.APPLICATION_XML_TYPE));
     
    multiPartReader.saveFile(multiPart);

    file = new File(fileName);
    Assert.assertNotNull(file);
    Assert.assertTrue(file.getTotalSpace() > 0);
    file.delete();
}

但是,就像我说的,我得到了一个

IllegalArgumentException [B cannot be cast to com.sun.jersey.multipart.BodyPartEntity

    BodyPartEntity bpe = (BodyPartEntity) multiPart.getBodyParts().get(0).getEntity();

那么我可以做些什么来模拟 jersey 处理的发送/接收,以便我的测试将获得与部署在服务器上并由 REST 客户端请求的 REST 服务相同的数据?

编辑

使用

BodyPartEntity bpe = multiPart.getBodyParts().get(0).getEntityAs(BodyPartEntity.class);

会抛出一个

IllegalStateException: Entity instance does not contain the unconverted content

我认为,在调用我的 MultiPartReader 之前,必须以某种方式转换测试生成的 MultiPart。

球衣中必须有一些方法,我可以调用它来进行转换..?

4

1 回答 1

0

查看我看到的jersey-multipart文档:

“目前无法提前知道应用程序希望为每个单独的正文部分使用哪个 Java 类,因此无法选择合适的 Provider。目前,返回每个正文部分的未解析内容(作为字节数组) 在返回的 BodyPart} 实例的实体属性中,应用程序可以根据该正文部分中包含的标头决定需要哪些进一步的步骤。最简单的技术是检查接收到的 BodyPart,然后调用 getEntityAs() 方法一旦你知道你更喜欢哪个实现类。”

看来您需要遵循该建议。检查服务器端 MultiPartReader 代码中返回的字节数组:

multiPart.getBodyParts().get(0).getEntity();

...并在 BodyPart 上调用 getEntityAs()。

于 2013-01-22T16:36:17.430 回答