我的javax应用程序中有一个类充当代理,并为POST请求创建多部分表单数据。在回归测试(对servlet的实际调用)期间,应用程序按预期执行,但是,我的单元测试继续失败。这是我单元测试中抛出异常的行,String httpPostBody = IOUtils.toString(httpPost.getEntity().getContent());
,特别是httpPost.getEntity().getContent()
。
全单元测试
@Test
public void testCreatePostRequest() throws IOException, ServletException, URISyntaxException, NullPointerException {
URI newTargetUri = new URI(targetUriPost);
cdsRequestBuilder = new CDSRequestBuilder();
HttpPost httpPost = cdsRequestBuilder.createPostRequest(mockClientRequest, newTargetUri);
// Parse the entity
String httpPostBody = IOUtils.toString(httpPost.getEntity().getContent());
// Perform evaluation
Assert.assertNotNull(httpPost);
Assert.assertEquals(httpPost.getHeaders(HttpHeaders.HOST)[0].toString(), ("Host: " + newTargetUri.getHost()));
Assert.assertTrue(httpPost.getHeaders(HttpHeaders.CONTENT_LENGTH).length == 0);
Assert.assertTrue(httpPostBody.contains("payload"));
Assert.assertTrue(httpPostBody.contains("file"));
Assert.assertTrue(httpPostBody.contains(testFileBinaryData));
}
方法调用此方法。
private HttpEntity convertInputStreamToMultiPart(Collection<Part> clientParts, String boundary) throws IOException {
Part payload = null;
Part file = null;
for (Part part : clientParts) {
if (part.getName().equalsIgnoreCase("payload")) {
payload = part;
} else if (part.getName().equalsIgnoreCase("file")) {
file = part;
}
}
if(payload == null) {
logIt.error("Failed to extract payload - no payload found");
throw new IllegalStateException("Payload is missing from client request.");
}
if(file == null || file.getSubmittedFileName().length() == 0) {
logIt.error("Failed to extract file - no file found");
throw new IllegalStateException("File is missing from client request.");
}
logIt.info("Payload is parsed from client: {}", IOUtils.toString(payload.getInputStream()));
return MultipartEntityBuilder.create()
.addTextBody("payload", IOUtils.toString(payload.getInputStream()))
.addBinaryBody("file", file.getInputStream(), ContentType.parse("application/pdf"), file.getSubmittedFileName())
.setContentType(ContentType.parse(MediaType.APPLICATION_FORM_URLENCODED))
.setBoundary(boundary)
.build();
}
以前,当我将文件输入流临时保存到file对象,然后使用它填充二进制体时,这个单元测试通过了,但是作为性能测试的结果,我决定简单地传递文件输入流本身。注意,在我的单元测试中,我模拟文件输入流如下:Part mockFilePart = mock(Part.class);
when(mockFilePart.getName()).thenReturn("file");
when(mockFilePart.getSubmittedFileName()).thenReturn(testFileName);
when(mockFilePart.getInputStream()).thenReturn(IOUtils.toInputStream(testFileBinaryData));
完全例外
org.apache.http.ContentTooLongException: Content length is unknown
at org.apache.http.entity.mime.MultipartFormEntity.getContent(MultipartFormEntity.java:101)
at gov.va.cds.test.CDSRequestBuilderTest.testCreatePostRequest(CDSRequestBuilderTest.java:117)
发布于 2022-06-21 14:47:46
修好了!因此,由于httpPost.getEntity().getContent()在最终发送请求之前总是有一个未知的内容长度,所以我研究了获取内容的其他方法,即使用ByteArrayOutputStream。然后,我做了几个转换,让它返回到一个字符串来执行我的断言。单元测试现在看起来是这样的。
// Parse the entity - has to be done this way for the unit test b/c the content length isn't set until final request is made
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
httpPost.getEntity().writeTo(byteArrayOutputStream); // keeps us from calling getContent which will throw Content Length unknown
String httpPostBody = IOUtils.toString(byteArrayOutputStream.toByteArray()); // now we can evaluate this
byteArrayOutputStream.close();
https://stackoverflow.com/questions/72627329
复制相似问题