python - 用工厂男孩测试 Django 的外键不起作用

标签 python django testing factory-boy

我在 library factory boy 中遇到外键问题。我的测试没有执行 我认为是外键的问题。

我尝试测试 user.models 中的用户模型,这就是我的代码的样子

class Task(models.Model):
    title = models.CharField(max_length=255, verbose_name='Заголовок')
    description = models.CharField(max_length=255, verbose_name='Описание')
    cost = models.DecimalField(max_digits=7, decimal_places=2, default=0, verbose_name='Цена')
    assignee = models.ForeignKey('users.User', related_name='assignee', null=True, verbose_name='Исполнитель')
    created_by = models.ForeignKey('users.User', related_name='created_by', verbose_name='Кем был создан')

    def __str__(self):
        return self.title

我用 factory boy 测试了一下,这就是我的 factory boy 类的样子

class UserFactoryCustomer(factory.Factory):

    class Meta:
        model = User

    first_name = 'Ahmed'
    last_name = 'Asadov'
    username = factory.LazyAttribute(lambda o: slugify(o.first_name + '.' + o.last_name))
    email = factory.LazyAttribute(lambda a: '{0}.{1}@example.com'.format(a.first_name, a.last_name).lower())
    user_type = 1
    balance = 10000.00

class UserFactoryExecutor(factory.Factory):

    class Meta:
        model = User

    first_name = 'Uluk'
    last_name = 'Djunusov'
    username = factory.LazyAttribute(lambda o: slugify(o.first_name + '.' + o.last_name))
    email = factory.LazyAttribute(lambda a: '{0}.{1}@example.com'.format(a.first_name, a.last_name).lower())
    user_type = 2
    balance = 5000.00


class TaskFactory(factory.Factory):

    class Meta:
        model = Task

    title = factory.Sequence(lambda n: 'Title {}'.format(n))
    description = factory.Sequence(lambda d: 'Description {}'.format(d))
    cost = 5000.00
    assignee = factory.SubFactory(UserFactoryExecutor)
    created_by = factory.SubFactory(UserFactoryCustomer)

那是我测试的例子

class ApiModelTestCase(TestCase):

     def test_creating_models_instance(self):
         executor = factories.UserFactoryExecutor()
         customer = factories.UserFactoryCustomer()
         Task.objects.create(title="Simple Task", description="Simple Description", cost="5000.00",
                            assignee=executor, created_by=customer)

这是我的错误

ERROR: test_creating_models_instance (tests.test_models.ApiModelTestCase)

Traceback (most recent call last):
  File "/Users/heartprogrammer/Desktop/freelance-with-api/freelance/tests/test_models.py", line 12, in test_creating_models_instance
    assignee=executor, created_by=customer)
  File "/Users/heartprogrammer/Documents/envs/freelance/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/heartprogrammer/Documents/envs/freelance/lib/python3.6/site-packages/django/db/models/query.py", line 394, in create
    obj.save(force_insert=True, using=self.db)
  File "/Users/heartprogrammer/Documents/envs/freelance/lib/python3.6/site-packages/django/db/models/base.py", line 763, in save
    "unsaved related object '%s'." % field.name
ValueError: save() prohibited to prevent data loss due to unsaved related object 'assignee'.

最佳答案

该错误表明受让人实例未保存。试试这个

class ApiModelTestCase(TestCase):

     def test_creating_models_instance(self):
         executor = factories.UserFactoryExecutor.create()
         customer = factories.UserFactoryCustomer.create()
         Task.objects.create(title="Simple Task", description="Simple Description", cost="5000.00",
                            assignee=executor, created_by=customer)

更新:

If you work with Django models, you need to use factory.django.DjangoModelFactory — otherwise, factory_boy uses the "simple Python object" approach. https://github.com/FactoryBoy/factory_boy/issues/329

应该是这样

from factory.django import DjangoModelFactory

class UserFactoryCustomer(DjangoModelFactory):

    class Meta:
        model = User

    first_name = 'Ahmed'
    last_name = 'Asadov'
    username = factory.LazyAttribute(lambda o: slugify(o.first_name + '.' + o.last_name))
    email = factory.LazyAttribute(lambda a: '{0}.{1}@example.com'.format(a.first_name, a.last_name).lower())
    user_type = 1
    balance = 10000.00

class UserFactoryExecutor(DjangoModelFactory):

    class Meta:
        model = User

    first_name = 'Uluk'
    last_name = 'Djunusov'
    username = factory.LazyAttribute(lambda o: slugify(o.first_name + '.' + o.last_name))
    email = factory.LazyAttribute(lambda a: '{0}.{1}@example.com'.format(a.first_name, a.last_name).lower())
    user_type = 2
    balance = 5000.00

关于python - 用工厂男孩测试 Django 的外键不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46440910/

相关文章:

python - 解析 xml 时保留实体引用

Python 单元测试 : Automatically Running the Debugger when a test fails

python - 将列组织和排序到字典变量中

python - 外键模型的django计数

python - 如何使用 django allauth 实现邀请流程以进行注册/登录?

python - Pandas 到 PySpark : transforming a column of lists of tuples to separate columns for each tuple item

django - 如何将两个查询混合为一个作为下拉元素

java - 是否有针对 'mock' mongo 交互的 MongoDB java 测试框架?

Android Beta 测试社区中的测试人员收到不同的版本

testing - 我应该如何在 Mocha 中测试客户端/服务器socket.io?