模拟Django中的测试图像

时间:2015-06-30 12:16:40

标签: python django unit-testing

我想使用mock-image在 Django 中创建一个对象。

tests.py

from django.test import TestCase
from .models import MyModel
from unittest import mock
from django.core.files import File


class MyModelTestCase(TestCase):

    def setUp(self):
        file_mock = mock.Mock(spec=File, name='FileMock')
        file_mock.name = 'test.png'
        MyModel.objects.create(img=file_mock, name='123',)

    def test_creation(self):
        obj =  MyModel.objects.get(name='123')
        self.assertEqual(obj, '1, 123')

但我有一个错误:

TypeError: 'Mock' does not support the buffer interface

我使用 spec -argument,它在documentation中的描述。

为什么它不起作用以及如何解决这个问题?

谢谢!

更新

如果我在 setUp()

中使用它
file_mock.read.return_value = b'my_img_data'

然后运行测试,没有任何反应:

Creating test database for alias 'default'...

所以,没有错误,没有运行测试。

更新1:

在setUP()中:

image = Image.new('RGBA', size=(50,50), color=(256,0,0))
image_file = BytesIO(image.tostring())
file = InMemoryUploadedFile(image_file, None, 'test.jpg', 'image/jpg', 1024, None)
MyModel.objects.create(img=file, name='123',) 

它会产生新的错误:

TypeError: 'NoneType' object is not subscriptable

回溯:

Creating test database for alias 'default'...
E
======================================================================
ERROR: test_creation ()
----------------------------------------------------------------------
Traceback (most recent call last):
  File "dir/graffities/tests.py", line 21, in setUp
    MyModel.objects.create(img=file, name='123',)
  File "dir/env/lib/python3.4/site-packages/django/db/models/manager.py", line 127, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "dir/env/lib/python3.4/site-packages/django/db/models/query.py", line 346, in create
    obj = self.model(**kwargs)
  File "dir/env/lib/python3.4/site-packages/django/db/models/base.py", line 482, in __init__
    signals.post_init.send(sender=self.__class__, instance=self)
  File "dir/env/lib/python3.4/site-packages/django/dispatch/dispatcher.py", line 201, in send
    response = receiver(signal=self, sender=sender, **named)
  File "dir/env/lib/python3.4/site-packages/django/db/models/fields/files.py", line 477, in update_dimension_fields
    width = file.width
  File "dir/env/lib/python3.4/site-packages/django/core/files/images.py", line 17, in _get_width
    return self._get_image_dimensions()[0]
TypeError: 'NoneType' object is not subscriptable

----------------------------------------------------------------------
Ran 1 test in 0.071s

FAILED (errors=1)

更新2:

models.py:

class MyModel(models.Model):
    width = models.PositiveIntegerField(editable=False,)
    height = models.PositiveIntegerField(editable=False,)
    img = models.ImageField(upload_to = get_file_path, height_field='height', width_field='width')
    name = models.CharField('Название', max_length=50)

1 个答案:

答案 0 :(得分:2)

您是否尝试过使用MagicMock?不过,我怀疑它会有所帮助。问题是,MyModel.objects.create要求模拟对象在.read()实例上调用file_mock之类的方法时返回有用的值。但是,模拟只是首先返回模拟,并且您必须配置模拟的返回值和属性,以便MyModel.objects.create可以使用它。 根据您对数据库中图像文件的处理方式,我假设一个简单的StringIO实例,其中任意数据可能足以为图像文件提供存根。

<强>更新

您的MyModel.objects.create(img=file, name='123',)需要django.core.files.ImageFile个实例。因此,您需要将BytesIO缓冲区传递给ImageFile,并且您可能必须图像保存到缓冲区中,我不确定{{1}会工作:

Image.tostring