如何模拟ManyToMany字段?

我要测试以下模型:

# 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'),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.nameself.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.nameself.surname(就像我在上面的代码中一样)还是仅使用namesurname?有区别吗?

谢谢

编辑:就像我在评论中建议的

    self.name._state = Mock()
    self.surname._state = Mock()

但是它给出了这个错误:

Traceback (most recent call last):
  File "E:\progetti\ElencoNomi\lists\tests\test_models.py",line 81,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.surname]
        )

但这真的是我想要的吗?

h402482070 回答:如何模拟ManyToMany字段?

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)
本文链接:https://www.f2er.com/3163417.html

大家都在问