任务
我们希望基于其MultiPart输入对执行文件操作的类进行单元测试.注意:Wo不想使用Jersey-Test! Grizzly没有加载我们需要将DAO和fileHandler服务注入REST服务类的spring应用程序上下文.我们明确要测试我们的fileHandler服务如何处理multiPart数据.
然而问题是,从REST客户端发出的MultiPart与REST服务器接收的MultiPart不同,因为jersey可能会对数据进行流式传输或其他任何操作.尝试测试(见下文)以下设置将导致
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,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_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();
那么我该怎样做才能模拟由泽西处理的发送/接收,以便我的测试将获得与我的REST服务部署在服务器上并由REST客户端请求相同的数据?
编辑
运用
BodyPartEntity bpe = multiPart.getBodyParts().get(0).getEntityAs(BodyPartEntity.class);
会抛出一个
IllegalStateException: Entity instance does not contain the unconverted content
我认为,在调用我的MultiPartReader之前,还需要以某种方式转换测试生成的MultiPart.
在jersey中必须有一些方法,我可以调用它来执行此转换它的方式,当它在已部署的系统上发出MultiPart请求时,或者可能是接收端在接收HTTP请求时进行一些解析..?
解决方法
“目前还不可能提前知道应用程序希望为每个单独的正文部分使用什么Java类,因此无法选择适当的提供程序.目前,返回每个正文部分的未解析内容(作为字节数组) )在返回的BodyPart}实例的实体属性中,应用程序可以根据该主体部分中包含的头来决定需要哪些进一步的步骤.最简单的方法是检查收到的BodyPart,然后调用getEntityAs()方法一旦你知道你想要哪个实现类.“
看起来你需要遵循这个建议.检查Server Side MultiPartReader代码中返回的字节数组:
multiPart.getBodyParts().get(0).getEntity();
…并在BodyPart上调用getEntityAs().