使用ImageField的Django测试模型

时间:2014-10-10 11:53:30

标签: python django testing mocking

我需要测试我的Django应用程序的Photo模型。如何使用测试图像文件模拟ImageField?

tests.py

class PhotoTestCase(TestCase):

    def test_add_photo(self):
        newPhoto = Photo()
        newPhoto.image = # ??????
        newPhoto.save()
        self.assertEqual(Photo.objects.count(), 1)

7 个答案:

答案 0 :(得分:55)

对于未来的用户,我已经解决了这个问题。 您可以使用SimpleUploadedFile实例模拟ImageField。

<强> test.py

from django.core.files.uploadedfile import SimpleUploadedFile

newPhoto.image = SimpleUploadedFile(name='test_image.jpg', content=open(image_path, 'rb').read(), content_type='image/jpeg')

答案 1 :(得分:17)

告诉模拟库基于Django的File类

创建一个模拟对象
import mock
from django.core.files import File

file_mock = mock.MagicMock(spec=File, name='FileMock')

然后在你的测试中使用

newPhoto.image = file_mock

答案 2 :(得分:11)

您可以使用tempfile使用临时文件。因此,您不需要真正的文件来进行测试。

import tempfile

image = tempfile.NamedTemporaryFile(suffix=".jpg").name

如果您希望进行手动清理,请改用tempfile.mkstemp()

答案 3 :(得分:4)

如果你不想在文件系统中创建一个实际的文件,你可以使用这个37字节的GIF,小到你的代码中的字节文字:

from django.core.files.uploadedfile import SimpleUploadedFile

small_gif = (
    b'\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x00\x00\x00\x21\xf9\x04'
    b'\x01\x0a\x00\x01\x00\x2c\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02'
    b'\x02\x4c\x01\x00\x3b'
)
uploaded = SimpleUploadedFile('small.gif', small_gif, content_type='image/gif')

答案 4 :(得分:2)

您可以做一些其他事情,以(1)避免保留专用的测试映像,以及(2)确保在测试后立即删除所有在测试期间创建的测试文件:

import shutil
import tempfile

from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase, override_settings

MEDIA_ROOT = tempfile.mkdtemp()

@override_settings(MEDIA_ROOT=MEDIA_ROOT)
class MyTest(TestCase):

    @classmethod
    def tearDownClass(cls):
        shutil.rmtree(MEDIA_ROOT, ignore_errors=True)  # delete the temp dir
        super().tearDownClass()

    def test(self):
        img = SimpleUploadedFile('test.jpg', b'whatevercontentsyouwant')
        # ^-- this will be saved in MEDIA_ROOT
        # do whatever ...

答案 5 :(得分:0)

我的方法是如何在无意传递任何有用数据的情况下测试模型:

from django.core.files import File
SomeModel.objects.create(image=File(file=b""))

答案 6 :(得分:0)

让某人尝试使用python 3.xx进行上传图像测试

我对Maxim Panfilov的出色答案一无所知,可以用独立的名字制作更多的虚拟图像。

from io import BytesIO
from PIL import Image
from django.core.files.base import File

#in your TestCase class:
class TestClass(TestCase):
    @staticmethod
    def get_image_file(name, ext='png', size=(50, 50), color=(256, 0, 0)):
        file_obj = BytesIO()
        image = Image.new("RGBA", size=size, color=color)
        image.save(file_obj, ext)
        file_obj.seek(0)
        return File(file_obj, name=name)

    def test_upload_image(self):
        c= APIClient()
        image1 = self.get_image('image.png')
        image2 = self.get_image('image2.png')
        data = 
            { 
                "image1": iamge1,
                "image2": image2,
            }
        response = c.post('/api_address/', data ) 
        self.assertEqual(response.status_code, 201)