我想使用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)
答案 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