Django REST Framework大文件上传限制测试方案咨询
问题分析
你尝试的几种方法都存在问题:
- 方法1:生成超大字节串直接触发内存溢出,完全不可行。
- 方法2:
InMemoryUploadedFile的size参数需要传入整数,你传了lambda函数,实际生效的是BytesIO内容的长度("large_content"共13字节),所以验证器拿到的size是13。 - 方法3:你patch的是类的
size属性,但每个InMemoryUploadedFile实例初始化时都会设置自己的size属性,类属性的patch不会覆盖实例已有的属性,因此无效。 - 方法4:验证器直接读取
file.size属性,根本没调用os.path.getsize,mock这个方法完全没用。
正确测试方案
创建一个小体积的合法UploadedFile实例,然后patch该实例的size属性为超过限制的值,既不会触发内存溢出,又能让验证器读取到预期的超大size。
测试序列化器示例
from django.test import TestCase from django.core.files.uploadedfile import SimpleUploadedFile from unittest.mock import patch from your_app.serializers import YourImageSerializer # 替换为你的序列化器类 class FileUploadValidationTest(TestCase): def test_large_file_rejected(self): # 创建小文件避免内存问题 small_file = SimpleUploadedFile( name="test.jpg", content=b"small_test_content", content_type="image/jpeg" ) # Patch实例的size为1GB(超过100MB限制) with patch.object(small_file, 'size', new=10**9): serializer = YourImageSerializer(data={"image_file": small_file}) # 验证不通过 self.assertFalse(serializer.is_valid()) # 检查错误信息 self.assertIn("image_file", serializer.errors) self.assertEqual( serializer.errors["image_file"][0], "Maximum file size is 100000000.0" )
测试API接口示例
如果你想直接测试上传接口而非序列化器:
def test_upload_large_file_api(self): small_file = SimpleUploadedFile("test.jpg", b"small", content_type="image/jpeg") with patch.object(small_file, 'size', new=10**9): client = APIClient() response = client.post( "/your/upload/endpoint/", # 替换为你的接口路径 {"image_file": small_file}, format="multipart" ) # 验证返回400错误 self.assertEqual(response.status_code, 400) self.assertIn("image_file", response.data)
可选优化:友好的错误提示
你可以修改验证器,将字节数格式化为更易读的单位:
def get_file_size_validator(max_size_bytes): def validator_func(file): if file.size > max_size_bytes: max_size_mb = max_size_bytes / (1024 * 1024) raise ValidationError(f"Maximum file size is {max_size_mb:.1f}MB") return validator_func
内容的提问来源于stack exchange,提问作者Huzaifa Qamer
相关产品推荐
相关产品推荐

