我正在为Django代码编写一些测试,并且正在模拟文件和文件存储。
我已经找到了本指南
https://joeray.me/mocking-files-and-file-storage-for-testing-django-models.html
所以我的模拟看起来像这样
# mocks.py
image_mock = mock.MagicMock(spec=File, name='FileMock')
image_mock.name = 'dummy.jpg'
storage_mock = mock.MagicMock(spec=Storage, name='StorageMock')
storage_mock.url = mock.MagicMock(name='url')
storage_mock.url.return_value = '/tmp/dummy.jpg'
任何失败的测试都是这样的:
import factory
import mock
from imagekit.signals import source_saved
from .mocks import storage_mock, image_mock
from .models import Car
@factory.django.mute_signals(source_saved)
class CarFactory(factory.django.DjangoModelFactory):
class Meta:
model = Car
image = image_mock
def test_case_one(self):
with mock.patch('django.core.files.storage.default_storage._wrapped', storage_mock):
car = CarFactory.create()
它失败并显示以下错误:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/factory/base.py:564: in create
return cls._generate(enums.CREATE_STRATEGY, kwargs)
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/factory/django.py:337: in wrapped_generate
return generate_method(*args, **kwargs)
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/factory/django.py:141: in _generate
return super(DjangoModelFactory, cls)._generate(strategy, params)
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/factory/base.py:501: in _generate
return step.build()
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/factory/builder.py:279: in build
kwargs=kwargs,
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/factory/base.py:315: in instantiate
return self.factory._create(model, *args, **kwargs)
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/factory/django.py:185: in _create
return manager.create(*args, **kwargs)
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/django/db/models/manager.py:82: in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/django/db/models/query.py:422: in create
obj.save(force_insert=True, using=self.db)
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/django/db/models/base.py:741: in save
force_update=force_update, update_fields=update_fields)
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/django/db/models/base.py:779: in save_base
force_update, using, update_fields,
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/django/db/models/base.py:870: in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/django/db/models/base.py:908: in _do_insert
using=using, raw=raw)
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/django/db/models/manager.py:82: in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/django/db/models/query.py:1186: in _insert
return query.get_compiler(using=using).execute_sql(return_id)
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/django/db/models/sql/compiler.py:1334: in execute_sql
for sql, params in self.as_sql():
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/django/db/models/sql/compiler.py:1278: in as_sql
for obj in self.query.objs
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/django/db/models/sql/compiler.py:1278: in <listcomp>
for obj in self.query.objs
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/django/db/models/sql/compiler.py:1277: in <listcomp>
[self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/django/db/models/sql/compiler.py:1218: in prepare_value
value = field.get_db_prep_save(value, connection=self.connection)
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/django/db/models/fields/__init__.py:789: in get_db_prep_save
return self.get_db_prep_value(value, connection=connection, prepared=False)
/home/admin/.virtualenvs/car-project/lib/python3.7/site-packages/django/db/models/fields/__init__.py:784: in get_db_prep_value
value = self.get_prep_value(value)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <django.db.models.fields.files.ImageField: image>
value = <[TypeError("__str__ returned non-string (type MagicMock)") raised in repr()] ImageFieldFile object at 0x7f2c94996a58>
def get_prep_value(self, value):
value = super().get_prep_value(value)
# Need to convert File objects provided via a form to string for database insertion
if value is None:
return None
> return str(value)
E TypeError: __str__ returned non-string (type MagicMock)
对此我将不胜感激。
要求:
python 3.7
Django == 2.2
django-storages == 1.7.1
factory-boy == 2.12.0
mock == 3.0.5
答案 0 :(得分:0)
您还必须像这样修补ImageField
image_name = 'test_image.jpg'
image_field_mock = mock.MagicMock(name='get_db_prep_save')
image_field_mock.return_value = image_name
def test_case_one(self):
with mock.patch('django.core.files.storage.default_storage._wrapped', storage_mock):
with mock.patch('django.db.models.ImageField.get_db_prep_save', image_field_mock):
car = CarFactory.create()