英文:
Write test for large file size. Django rest framwork
问题
在我的Django应用程序中,有一个处理文件上传的端点。在序列化器中,我定义了文件大小验证如下:
extra_kwargs = {
"image_file": {
"validators": [
get_file_size_validator(1e8),
],
},
}
验证器函数如下所示:
def get_file_size_validator(file_size):
def validator_func(file):
if file_size < file.size:
raise ValidationError(f"Maximum file size is {file_size}")
return validator_func
我想编写一个测试,测试用户无法上传大文件。
我迄今为止尝试过的方法:
SimpleUploadedFile("foo.pdf", b"aaaaa" * (9**10), content_type="image/jpeg")
InMemoryUploadedFile(BytesIO(b"large_content"), None, "foo.jpg", "image/jpeg", lambda: 1e9, None, None)
- 使用
mock.patch.object(InMemoryUploadedFile, "size", return_value=1e9):
- 将
os.path.getsize
模拟为这里推荐的方式:https://stackoverflow.com/a/35246275/1847898
第一个解决方案导致MemoryError,对于其他所有解决方案,validator_func
中的文件大小都返回13。
有什么想法如何实现这一目标?
英文:
In my Django application there is an endpoint that handles file upload. In the serializer I define the file size validation like below
extra_kwargs = {
"image_file": {
"validators": [
get_file_size_validator(1e8),
],
},
The validator function looks like this
def get_file_size_validator(file_size):
def validator_func(file):
if file_size < file.size:
raise ValidationError(f"Maximum file size is {file_size}")
return validator_func
I would like to write a test where I want to test that user cannot upload large files.
What I have tried so far.
SimpleUploadedFile("foo.pdf", b"aaaaa" * (9**10), content_type="image/jpeg")
InMemoryUploadedFile(BytesIO(b"large_content"), None, "foo.jpg", "image/jpeg", lambda: 1e9, None, None)
- Used
mock.patch.object(InMemoryUploadedFile, "size", return_value=1e9):
- Mocked
os.path.getsize
as recommended here https://stackoverflow.com/a/35246275/1847898
The first solution gives me MemoryError and for all the others file size is returned as 13 in validator_func
Any ideas how I can achieve this?
答案1
得分: 2
你应该模拟MemoryFileUploadHandler.file_complete
方法,而不是SimpleUploadedFile
或InMemoryUploadedFile
。
from unittest.mock import patch
from django.core.files.uploadedfile import InMemoryUploadedFile, SimpleUploadedFile
from rest_framework.test import APITestCase
class TestUploadAPI(APITestCase):
url = "/api/to/the/end-point/"
@patch("django.core.files.uploadhandler.MemoryFileUploadHandler.file_complete")
def test_validate_size(self, mock_file_complete):
file_name = "any-file-name"
file_content_type = "image/png"
max_size = 1e8
mock_file_complete.return_value = InMemoryUploadedFile(
file=b"",
field_name=None,
name=file_name,
content_type=file_content_type,
size=max_size + 1,
charset=None,
)
file = SimpleUploadedFile(
name=file_name,
content=b"",
content_type=file_content_type,
)
response = self.client.post(self.url, {"file": file})
self.assertEqual(response.status_code, 400)
self.assertEqual(
response.json(),
{
"file": ["Maximum file size is 100000000.0"],
},
)
mock_file_complete.assert_called_once()
英文:
You should mock the MemoryFileUploadHandler.file_complete
method instead of SimpleUploadedFile
or InMemoryUploadedFile
.
from unittest.mock import patch
from django.core.files.uploadedfile import InMemoryUploadedFile, SimpleUploadedFile
from rest_framework.test import APITestCase
class TestUploadAPI(APITestCase):
url = "/api/to/the/end-point/"
@patch("django.core.files.uploadhandler.MemoryFileUploadHandler.file_complete")
def test_validate_size(self, mock_file_complete):
file_name = "any-file-name"
file_content_type = "image/png"
max_size = 1e8
mock_file_complete.return_value = InMemoryUploadedFile(
file=b"",
field_name=None,
name=file_name,
content_type=file_content_type,
size=max_size + 1,
charset=None,
)
file = SimpleUploadedFile(
name=file_name,
content=b"",
content_type=file_content_type,
)
response = self.client.post(self.url, {"file": file})
self.assertEqual(response.status_code, 400)
self.assertEqual(
response.json(),
{
"file": ["Maximum file size is 100000000.0"],
},
)
mock_file_complete.assert_called_once()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论