显然我没有正确使用这个测试夹具。我的servlet在tomcat中运行得很好,但是当我尝试使用这个模拟时,找不到多部分边界。 "请求被拒绝,因为没有找到多部分边界"。
答案here显示了如何使用文本文件来使用它,但该答案明确设置了边界字符串并将文件嵌入为test。我认为我不需要手动处理像 mockrequest.addFile (...)
这样的方法我没有在这里做什么,或者我这样做是怎么回事?
@org.testng.annotations.Test
public void testDoPost() throws Exception
{
MockMultipartFile file = new MockMultipartFile("test.zip", "test.zip", "application/zip", MyServletTest.class.getResourceAsStream("/test.zip"));
MockMultipartHttpServletRequest mockRequest = new MockMultipartHttpServletRequest();
mockRequest.addFile(file);
mockRequest.set
mockRequest.setMethod("POST");
mockRequest.setParameter("variant", "php");
mockRequest.setParameter("os", "mac");
mockRequest.setParameter("version", "3.4");
MockHttpServletResponse response = new MockHttpServletResponse();
new MyServletTest().doPost(mockRequest, response);
// BOOM !
}
这是例外
Caused by: blablah: the request was rejected because no multipart boundary was found
答案 0 :(得分:14)
您需要设置边界。
这里有一个关于边界https://stackoverflow.com/a/10932533/2762092
的很好的解释要解决您的问题,请尝试使用此代码。
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.mock.web.MockMultipartHttpServletRequest;
public class FileUploadTest {
public void testDoPost() throws IOException {
Path path = Paths.get("c:\\temp\\test.zip");
byte[] data = Files.readAllBytes(path);
MockMultipartFile file = new MockMultipartFile("test.zip", "test.zip",
"application/zip", data);
MockMultipartHttpServletRequest mockRequest = new MockMultipartHttpServletRequest();
String boundary = "q1w2e3r4t5y6u7i8o9";
mockRequest.setContentType("multipart/form-data; boundary="+boundary);
mockRequest.setContent(createFileContent(data,boundary,"application/zip","test.zip"));
mockRequest.addFile(file);
mockRequest.setMethod("POST");
mockRequest.setParameter("variant", "php");
mockRequest.setParameter("os", "mac");
mockRequest.setParameter("version", "3.4");
MockHttpServletResponse response = new MockHttpServletResponse();
new FileUpload().doPost(mockRequest, response);
}
public byte[] createFileContent(byte[] data, String boundary, String contentType, String fileName){
String start = "--" + boundary + "\r\n Content-Disposition: form-data; name=\"file\"; filename=\""+fileName+"\"\r\n"
+ "Content-type: "+contentType+"\r\n\r\n";;
String end = "\r\n--" + boundary + "--"; // correction suggested @butfly
return ArrayUtils.addAll(start.getBytes(),ArrayUtils.addAll(data,end.getBytes()));
}
}
答案 1 :(得分:3)
塞缪尔的答案很好,但是一个错误:
String end = "\r\n"+ boundary + "--";
应该是:
String end = "--"+ boundary + "--";
非常感谢他的工作。
答案 2 :(得分:3)
为塞缪尔投票。虽然花了一天时间试图让它发挥作用。问题在于:
String end = "--" + boundary + "--";
应该是:
String end = "\r\n--" + boundary + "--";
答案 3 :(得分:0)
能够添加多个字段,
private byte[] createFileContents(String requestId, String date, String image, String invoiceNumber,String imageFile) {
String requestIdField = "--" + BOUNDARY + "\r\n Content-Disposition: form-data; name=\"" + REQUEST_ID_KEY
+ "\";" + "Content-type: " + CONTENT_TYPE + "\r\n value=\"12345\"" + "\r\n\r\n";
String requestIdValue = requestId + "\r\n";
String numberFiledField = "--" + BOUNDARY + "\r\n Content-Disposition: form-data; name=\"" + NUMBER_KEY + "\";"
+ "Content-type: " + CONTENT_TYPE + "\r\n value=\"12345\"" + "\r\n\r\n";
String invoiceValue = invoiceNumber + "\r\n";
String dateField = "--" + BOUNDARY + "\r\n Content-Disposition: form-data; name=\"" + DATE_KEY + "\";"
+ "Content-type: " + CONTENT_TYPE + "\r\n value=\"12345\"" + "\r\n\r\n";
String dateValue = date + "\r\n";
String imageField = "--" + BOUNDARY + "\r\n Content-Disposition: form-data; name=\"" + IMAGE_KEY
+ "\"; filename=\"" + imageFile + "\"\r\n" + "Content-type: " + CONTENT_TYPE + "\r\n\r\n";
String imageValue = image + "\r\n";
String end = "\r\n--" + BOUNDARY + "--";
return ArrayUtils.addAll((requestIdField + requestIdValue + numberFiledField + invoiceValue + dateField
+ dateValue + imageField + imageValue).getBytes(), ArrayUtils.addAll(data, end.getBytes()));
}
答案 4 :(得分:0)
通过模拟MVC发送参数和文件来测试 multipart / form-data 的方法如下:
@Test
void testSendFeedback() throws Exception {
var builder = MockMvcRequestBuilders.multipart(URL_PATH);
Path path = Files.createTempFile("test-file", "tmp");
builder = builder.part(new MockPart("image", path.toFile().getName(), Files.readAllBytes(path)));
builder.param("field1", "value1")
.param("fields2", "value2");
mockMvc.perform(builder.header(HttpHeaders.AUTHORIZATION, YOUR_AUTH_VALUE).contentType(MediaType.MULTIPART_FORM_DATA_VALUE))
.andDo(print())
.andExpect(status().isNoContent());
}