编写用于大文件大小的测试。Django REST框架

huangapple go评论96阅读模式
英文:

Write test for large file size. Django rest framwork

问题

在我的Django应用程序中,有一个处理文件上传的端点。在序列化器中,我定义了文件大小验证如下:

  1. extra_kwargs = {
  2. "image_file": {
  3. "validators": [
  4. get_file_size_validator(1e8),
  5. ],
  6. },
  7. }

验证器函数如下所示:

  1. def get_file_size_validator(file_size):
  2. def validator_func(file):
  3. if file_size < file.size:
  4. raise ValidationError(f"Maximum file size is {file_size}")
  5. return validator_func

我想编写一个测试,测试用户无法上传大文件。

我迄今为止尝试过的方法:

  1. SimpleUploadedFile("foo.pdf", b"aaaaa" * (9**10), content_type="image/jpeg")
  2. InMemoryUploadedFile(BytesIO(b"large_content"), None, "foo.jpg", "image/jpeg", lambda: 1e9, None, None)
  3. 使用mock.patch.object(InMemoryUploadedFile, "size", return_value=1e9):
  4. 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

  1. extra_kwargs = {
  2. &quot;image_file&quot;: {
  3. &quot;validators&quot;: [
  4. get_file_size_validator(1e8),
  5. ],
  6. },

The validator function looks like this

  1. def get_file_size_validator(file_size):
  2. def validator_func(file):
  3. if file_size &lt; file.size:
  4. raise ValidationError(f&quot;Maximum file size is {file_size}&quot;)
  5. 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.

  1. SimpleUploadedFile(&quot;foo.pdf&quot;, b&quot;aaaaa&quot; * (9**10), content_type=&quot;image/jpeg&quot;)
  2. InMemoryUploadedFile(BytesIO(b&quot;large_content&quot;), None, &quot;foo.jpg&quot;, &quot;image/jpeg&quot;, lambda: 1e9, None, None)
  3. Used mock.patch.object(InMemoryUploadedFile, &quot;size&quot;, return_value=1e9):
  4. 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方法,而不是SimpleUploadedFileInMemoryUploadedFile

  1. from unittest.mock import patch
  2. from django.core.files.uploadedfile import InMemoryUploadedFile, SimpleUploadedFile
  3. from rest_framework.test import APITestCase
  4. class TestUploadAPI(APITestCase):
  5. url = &quot;/api/to/the/end-point/&quot;
  6. @patch(&quot;django.core.files.uploadhandler.MemoryFileUploadHandler.file_complete&quot;)
  7. def test_validate_size(self, mock_file_complete):
  8. file_name = &quot;any-file-name&quot;
  9. file_content_type = &quot;image/png&quot;
  10. max_size = 1e8
  11. mock_file_complete.return_value = InMemoryUploadedFile(
  12. file=b&quot;&quot;,
  13. field_name=None,
  14. name=file_name,
  15. content_type=file_content_type,
  16. size=max_size + 1,
  17. charset=None,
  18. )
  19. file = SimpleUploadedFile(
  20. name=file_name,
  21. content=b&quot;&quot;,
  22. content_type=file_content_type,
  23. )
  24. response = self.client.post(self.url, {&quot;file&quot;: file})
  25. self.assertEqual(response.status_code, 400)
  26. self.assertEqual(
  27. response.json(),
  28. {
  29. &quot;file&quot;: [&quot;Maximum file size is 100000000.0&quot;],
  30. },
  31. )
  32. mock_file_complete.assert_called_once()
英文:

You should mock the MemoryFileUploadHandler.file_complete method instead of SimpleUploadedFile or InMemoryUploadedFile.

  1. from unittest.mock import patch
  2. from django.core.files.uploadedfile import InMemoryUploadedFile, SimpleUploadedFile
  3. from rest_framework.test import APITestCase
  4. class TestUploadAPI(APITestCase):
  5. url = &quot;/api/to/the/end-point/&quot;
  6. @patch(&quot;django.core.files.uploadhandler.MemoryFileUploadHandler.file_complete&quot;)
  7. def test_validate_size(self, mock_file_complete):
  8. file_name = &quot;any-file-name&quot;
  9. file_content_type = &quot;image/png&quot;
  10. max_size = 1e8
  11. mock_file_complete.return_value = InMemoryUploadedFile(
  12. file=b&quot;&quot;,
  13. field_name=None,
  14. name=file_name,
  15. content_type=file_content_type,
  16. size=max_size + 1,
  17. charset=None,
  18. )
  19. file = SimpleUploadedFile(
  20. name=file_name,
  21. content=b&quot;&quot;,
  22. content_type=file_content_type,
  23. )
  24. response = self.client.post(self.url, {&quot;file&quot;: file})
  25. self.assertEqual(response.status_code, 400)
  26. self.assertEqual(
  27. response.json(),
  28. {
  29. &quot;file&quot;: [&quot;Maximum file size is 100000000.0&quot;],
  30. },
  31. )
  32. mock_file_complete.assert_called_once()

huangapple
  • 本文由 发表于 2023年7月13日 12:09:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76675853.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定