Spring 使用MockMultipartFile测试最大上载文件大小

Spring 使用MockMultipartFile测试最大上载文件大小,spring,spring-mvc,spring-boot,spring-test,spring-test-mvc,Spring,Spring Mvc,Spring Boot,Spring Test,Spring Test Mvc,我用SpringBoot创建了一个文件上传服务,并用SpringMockMVC和MockMultipartFile对其进行了测试。我想测试当超过最大文件大小时是否抛出错误。以下测试失败,因为它接收到一个200 RandomAccessFile f = new RandomAccessFile("t", "rw"); f.setLength(1024 * 1024 * 10); InputStream is = Channels.newInputStream(f.getChannel()); M

我用SpringBoot创建了一个文件上传服务,并用SpringMockMVC和MockMultipartFile对其进行了测试。我想测试当超过最大文件大小时是否抛出错误。以下测试失败,因为它接收到一个200

RandomAccessFile f = new RandomAccessFile("t", "rw");
f.setLength(1024 * 1024 * 10);
InputStream is = Channels.newInputStream(f.getChannel());

MockMultipartFile firstFile = new MockMultipartFile("data", "file1.txt", "text/plain", is);

mvc.perform(fileUpload("/files")
    .file(firstFile))
    .andExpect(status().isInternalServerError());
是否有可能测试上传文件的大小?

根据:

如果length方法返回的文件的当前长度为 小于newLength参数,则文件将被扩展。在里面 在这种情况下,文件扩展部分的内容不会被删除 定义

请尝试以下方法:

byte[] bytes = new byte[1024 * 1024 * 10];
MockMultipartFile firstFile = new MockMultipartFile("data", "file1.txt", "text/plain", bytes);

这里也有同样的问题

不知道是否有更好的解决方案,但我创建了一个注释来验证上传的图像列表,并与其他人一起在那里进行了检查

  • 类来验证用户的图像
公共类ImageValidator实现ConstraintValidator{
@凌驾
公共布尔值是有效的(
列表listMultipartFile、ConstraintValidatorContext(上下文){
for(var multipartFile:listmultippartfile){
var msgValidation=图像验证(多部分文件);
如果(!msgValidation.isEmpty()){
context.disableDefaultConstraintViolation();
buildConstraintViolationWithTemplate(msgValidation).addConstraintViolation();
返回false;
}
}
返回true;
}
私有字符串图像验证(MultipartFile MultipartFile){
var contentType=multipartFile.getContentType();
如果(!isSupportedContentType(contentType)){
返回字符串格式(
“只允许使用JPG和PNG图像,提供了%s。”,multipartFile.getContentType());
}else if(multipartFile.isEmpty()){
return“它不能是空图像。”;
}else if(multipartFile.getSize()>(1024*1024)){
return“文件大小应不超过1MB”;
}
返回“”;
}
私有布尔isSupportedContentType(字符串contentType){
var supportedContents=List.of(“image/jpg”、“image/jpeg”、“image/png”);
返回supportedContents.contains(contentType);
}
}
  • 接口
@Target(ElementType.PARAMETER)
@保留(RetentionPolicy.RUNTIME)
@约束(validatedBy={ImageValidator.class})
public@interface ValidImage{
字符串消息()默认为“无效图像文件”;
类[]组()默认值{};

CLASS这对我不起作用。是否有可能MockMVC禁用了文件大小检查?@wuethrich44:看起来确实如此。我偶然发现了同样的问题,也找不到简单的解决方案。没有查看
spring web
的代码(或任何应该处理此问题的代码),我忍不住注意到一些Tomcat代码(即
java.lang.IllegalStateException:org.apache.Tomcat.util.http.fileupload.FileUploadBase$filesizelimiteExceedeException:字段文件超出了其最大允许大小1048576字节)引发了实际的异常(因为超出了限制)。
)。因此,可能Spring只是将此签出委托给底层应用程序服务器。@wuethrich44:而且由于
MockMvc
集成测试实际上并不包括实际的应用程序服务器…@priidune当Tomcat处理此错误时,似乎无法在
MockMvc
中测试。奇怪的是@David Jones成功了使用此解决方案…David可能正在进行手动大小检查以及/而不是使用Spring属性。您在哪里指定了最大上载大小?
    public class ImageValidator implements ConstraintValidator<ValidImage, List<MultipartFile>> {

      @Override
      public boolean isValid(
          List<MultipartFile> listMultipartFile, ConstraintValidatorContext context) {

        for (var multipartFile : listMultipartFile) {
          var msgValidation = imageValidations(multipartFile);

          if (!msgValidation.isEmpty()) {
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate(msgValidation).addConstraintViolation();
            return false;
          }
        }

        return true;
      }

      private String imageValidations(MultipartFile multipartFile) {
        var contentType = multipartFile.getContentType();

        if (!isSupportedContentType(contentType)) {
          return String.format(
              "Only JPG and PNG images are allowed, %s provided.", multipartFile.getContentType());
        } else if (multipartFile.isEmpty()) {
          return "It must not be an empty image.";
        } else if (multipartFile.getSize() > (1024 * 1024)) {
          return "File size should be at most 1MB";
        }

        return "";
      }

      private boolean isSupportedContentType(String contentType) {
        var supportedContents = List.of("image/jpg", "image/jpeg", "image/png");
        return supportedContents.contains(contentType);
      }
    }
    @Target(ElementType.PARAMETER)
    @Retention(RetentionPolicy.RUNTIME)
    @Constraint(validatedBy = {ImageValidator.class})
    public @interface ValidImage {
      String message() default "Invalid image file";

      Class<?>[] groups() default {};

      Class<? extends Payload>[] payload() default {};
    }