您无法使用 Spring 的 MockMultipartFile / MockMvc 对此进行测试。原因是错误的来源不是 Spring 本身,而是底层 Web 服务器(通常是 Tomcat),正如您在 MaxUploadSizeExceededException 的堆栈跟踪中看到的那样:
org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size of 500000 bytes exceeded; nested exception is org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (1065736) exceeds the configured maximum (500000)
at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:160)
at org.springframework.web.multipart.commons.CommonsMultipartResolver.resolveMultipart(CommonsMultipartResolver.java:139)
[...]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (1065736) exceeds the configured maximum (500000)
at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:965)
at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:310)
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:334)
at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:115)
at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:156)
... 20 more
当使用默认 MockMvc 并@SpringBootTest
使用其默认设置时,不会启动真正的 Web 服务器,因此不会发生错误。
但是,您可以通过提供来告诉 Spring 为您的测试启动一个真正的 Web 服务器@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
,这将(惊喜)在随机端口上启动一个 Web 服务器。您可以在测试类中使用@LocalServerPort
.
然后,您可以编写一个测试,对您的测试服务器执行真正的分段上传,而不是伪造的。REST Assured是一个库,除其他外,它可以做到这一点:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MyTest {
@LocalServerPort
private int port;
@Test
void testMultipartUpload() throws Exception {
File file = new File("my-file");
RestAssured.baseURI = "http://localhost/api";
RestAssured.port = port;
Response res = given()
.multiPart("data", file, "text/plain")
.when().post("/upload");
...
}
}
当您的上传过大时,此测试将显示服务器错误。