Django 测试模拟 ImageField 阻止上传或测试后清理
Django Test mocked ImageField prevent upload or clean after tests
我正在为我的项目开发一个测试用例,涉及一些图像和文件字段。一些对象加载了固定装置,一些对象是在测试期间创建的。我用 InMemoryUploadedFile 模拟了我的图像。
创建新测试对象时,正在上传模拟图像
到 MEDIA_ROOT 目录,在 upload_to 方法中定义的正确位置。
这些模拟图像实际上在测试期间存储在本地。有很多关于如何模拟图像 的信息。但是我真的找不到一些关于在测试后清理这些上传的好信息。
问题:
是否有可能阻止这些文件实际被上传,或者这是 impossible/dis-encouraged?
或
是否应该上传这些文件以支持测试(如果是,为什么?),然后在拆卸期间清理?什么是清理这些上传文件的合适方法?
我正在处理的当前情况的一些代码,已裁剪为适合问题的大小。我不是在寻找一个完整的样本,而是在寻找正确的方向。感谢您提前抽出时间。
已裁剪 模特:
def project_image_upload_location(instance, filename):
return 'uploads/projects/images/%s' % \
services.unique_filename(filename)
class ProjectImage(models.Model):
project = models.ForeignKey(
'projects.Project')
name = models.CharField(
_("Image name"),
max_length=35)
image = models.ImageField(
_("Project image"),
upload_to=project_image_upload_location,
width_field='image_width',
height_field='image_height')
image_width = models.IntegerField(
default=0)
image_height = models.IntegerField(
default=0)
裁剪 测试用例:
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.test import TestCase
from PIL import Image
import StringIO
from projects.models import ProjectImage
from projects import services
class ProjectsTest(TestCase):
fixtures = ['projects']
def _create_project_image(self, project, name):
return ProjectImage.objects.create(
project=project,
name=name,
description="Description",
image=self._create_mock_image(name="Mocked Image"),
is_primary=True,
is_published=True)
def _get_project_image(self, name):
return ProjectImage.objects.get(name=name)
def _create_mock_image(self, name):
name = name + '.jpg'
io = StringIO.StringIO()
size = (200,200)
color = (255,0,0)
image = Image.new("RGB", size, color)
image.save(io, format='JPEG')
image_file = InMemoryUploadedFile(io, None, name, 'jpeg', io.len, None)
image_file.seek(0)
return image_file
def test_update_project_set_updated_datetime(self):
project = self._get_project("Project B")
self.assertEqual(project.updated_datetime, None)
project.save()
self.assertTrue(isinstance(project.updated_datetime, datetime))
我已经改变了 testing-a-model-that-have-an-imagefield 的方法。图像将上传到临时目录。该指南建议删除 tearDown
中的目录。它可能会更新,因为 temp/ 目录已自动删除。所有测试都正确通过。
旧答案
我能够通过 joeray.me: mocking-files-and-file-storage-for-testing-django-models
在 default_storage
上使用 mock.patch()
模拟存储
<..crop..>
import mock
current_storage = 'django.core.files.storage.default_storage._wrapped'
def _mock_storage():
return mock.MagicMock(spec=Storage, name="StorageMock")
class ProjectsTest(TestCase):
fixtures = ['projects']
@mock.patch(current_storage, _mock_storage())
def _create_project(self, name):
return Project.objects.create(
name=name,
short_description="Short description A",
full_description="Full description A",
url="http://test-project-url.com/",
is_published=True)
不幸的是,我无法测试在 save()
方法中包含 update()
的模型:django-mocking-storage-on-model-with-update-throws-error
我正在为我的项目开发一个测试用例,涉及一些图像和文件字段。一些对象加载了固定装置,一些对象是在测试期间创建的。我用 InMemoryUploadedFile 模拟了我的图像。
创建新测试对象时,正在上传模拟图像 到 MEDIA_ROOT 目录,在 upload_to 方法中定义的正确位置。
这些模拟图像实际上在测试期间存储在本地。有很多关于如何模拟图像 的信息。但是我真的找不到一些关于在测试后清理这些上传的好信息。
问题:
是否有可能阻止这些文件实际被上传,或者这是 impossible/dis-encouraged?
或
是否应该上传这些文件以支持测试(如果是,为什么?),然后在拆卸期间清理?什么是清理这些上传文件的合适方法?
我正在处理的当前情况的一些代码,已裁剪为适合问题的大小。我不是在寻找一个完整的样本,而是在寻找正确的方向。感谢您提前抽出时间。
已裁剪 模特:
def project_image_upload_location(instance, filename):
return 'uploads/projects/images/%s' % \
services.unique_filename(filename)
class ProjectImage(models.Model):
project = models.ForeignKey(
'projects.Project')
name = models.CharField(
_("Image name"),
max_length=35)
image = models.ImageField(
_("Project image"),
upload_to=project_image_upload_location,
width_field='image_width',
height_field='image_height')
image_width = models.IntegerField(
default=0)
image_height = models.IntegerField(
default=0)
裁剪 测试用例:
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.test import TestCase
from PIL import Image
import StringIO
from projects.models import ProjectImage
from projects import services
class ProjectsTest(TestCase):
fixtures = ['projects']
def _create_project_image(self, project, name):
return ProjectImage.objects.create(
project=project,
name=name,
description="Description",
image=self._create_mock_image(name="Mocked Image"),
is_primary=True,
is_published=True)
def _get_project_image(self, name):
return ProjectImage.objects.get(name=name)
def _create_mock_image(self, name):
name = name + '.jpg'
io = StringIO.StringIO()
size = (200,200)
color = (255,0,0)
image = Image.new("RGB", size, color)
image.save(io, format='JPEG')
image_file = InMemoryUploadedFile(io, None, name, 'jpeg', io.len, None)
image_file.seek(0)
return image_file
def test_update_project_set_updated_datetime(self):
project = self._get_project("Project B")
self.assertEqual(project.updated_datetime, None)
project.save()
self.assertTrue(isinstance(project.updated_datetime, datetime))
我已经改变了 testing-a-model-that-have-an-imagefield 的方法。图像将上传到临时目录。该指南建议删除 tearDown
中的目录。它可能会更新,因为 temp/ 目录已自动删除。所有测试都正确通过。
旧答案
我能够通过 joeray.me: mocking-files-and-file-storage-for-testing-django-models
default_storage
上使用 mock.patch()
模拟存储
<..crop..>
import mock
current_storage = 'django.core.files.storage.default_storage._wrapped'
def _mock_storage():
return mock.MagicMock(spec=Storage, name="StorageMock")
class ProjectsTest(TestCase):
fixtures = ['projects']
@mock.patch(current_storage, _mock_storage())
def _create_project(self, name):
return Project.objects.create(
name=name,
short_description="Short description A",
full_description="Full description A",
url="http://test-project-url.com/",
is_published=True)
不幸的是,我无法测试在 save()
方法中包含 update()
的模型:django-mocking-storage-on-model-with-update-throws-error