我有这些模型要测试:
# models.py (simplified, name is a costum multilanguage field)
class NameType(models.Model):
name = models.CharField(_('nome'), max_length=25, unique=True)
class NameLanguage(models.Model):
name = models.CharField(_('nome'), max_length=25, unique=True)
syntax = models.ManyToManyField(
NameType, related_name='syntax_name',
verbose_name=_('sintassi'))
为了隔离我想使用的测试mock()
(我已经测试过NameType
)
# test_models.py
class NameLanguageTest(TestCase):
def test_language_created(self):
self.name = Mock(spec=NameType)
self.surname = Mock(spec=NameType)
self.romans = NameLanguage.objects.create(name='Romans')
self.romans.syntax.add(self.name)
self.romans.syntax.add(self.surname)
self.assertEqual(NameLanguage.objects.all().count(), 1)
self.assertEqual(
list(NameLanguage.objects.get(name='romans').syntax.all()),
[self.name, self.surname]
)
但是当我尝试将 self.name
和 self.surname
添加到 M2M syntax
时,它给我这个错误:
Traceback (most recent call last):
File "E:\progetti\ElencoNomi\lists\tests\test_models.py", line 79, in test_language_created
self.romans.syntax.add(self.name)
File "e:\progetti\envs\ElencoNomi\lib\site-packages\django\db\models\fields\related_descriptors.py", line 938, in add
through_defaults=through_defaults,
File "e:\progetti\envs\ElencoNomi\lib\site-packages\django\db\models\fields\related_descriptors.py", line 1039, in _add_items
if not router.allow_relation(obj, self.instance):
File "e:\progetti\envs\ElencoNomi\lib\site-packages\django\db\utils.py", line
280, in allow_relation
return obj1._state.db == obj2._state.db
File "E:\Python\Python37\lib\unittest\mock.py", line 593, in __getattr__
raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute '_state'
我还应该使用 self.name
和 self.surname
(就像我在上面的代码中所做的那样)还是只使用 name
和 姓氏
?有区别吗?
谢谢
编辑:就像我添加的评论中建议的那样
self.name._state = Mock()
self.surname._state = Mock()
但它给出了这个错误:
Traceback (most recent call last):
File "E:\progetti\ElencoNomi\lists\tests\test_models.py", line 81, in test_language_created
self.romans.syntax.add(self.name)
File "e:\progetti\envs\ElencoNomi\lib\site-packages\django\db\models\fields\related_descriptors.py", line 938, in add
through_defaults=through_defaults,
File "e:\progetti\envs\ElencoNomi\lib\site-packages\django\db\models\fields\related_descriptors.py", line 1042, in _add_items
(obj, self.instance._state.db, obj._state.db)
ValueError: Cannot add "<Mock spec='NameType' id='86024648'>": instance is on database "default", value is on database "<Mock name='mock._state.db' id='93279176'>"
编辑:
令我惊讶的是我无法模拟一个简单的 m2m 字段,无论如何使用 factory_boy 它都有效(也许,请检查):
# factories.py:
class NameTypeFactory(factory.DjangoModelFactory):
class Meta:
model = NameType
# test_models.py
class NameLanguageTest(TestCase):
def test_language_created(self):
self.name = NameTypeFactory()
self.surname = NameTypeFactory()
self.romans = NameLanguage.objects.create(
name_en='Romans', name_it='Romani')
self.romans.syntax.add(self.name)
self.romans.syntax.add(self.surname)
self.assertEqual(NameLanguage.objects.all().count(), 1)
self.assertEqual(
list(NameLanguage.objects.get(name_it='romani').syntax.all()),
[self.name, self.surname]
)
但这真的是我想要的吗?
最佳答案
Django 使用模型和表来运行测试,还有更复杂的库可以全面模拟您的数据(如果需要,甚至可以在数据库中创建它),例如 factory_boy
你可以做类似的事情
import factory, factory.django
from . import models
class NameTypeFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.NameType
class NameLanguageFactory(factory.django.DjangoModelFactory):
@factory.post_generation
def groups(self, create, extracted, **kwargs):
if create and extracted:
# A list of groups were passed in, use them
for group in extracted:
self.groups.add(group)
关于python - 如何模拟 ManyToMany 字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58701791/