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