python - 工厂男孩 - 如何创建工厂所需的数据(预生成 Hook )

标签 python django unit-testing factory factory-boy

注意:我将尝试用一个简化的场景来解释这个用例(这对你来说可能看起来很奇怪)。

我有 2 个模型(相关但没有外键):

# models.py
class User(models.Model):
    name = models.CharField()
    age = models.IntegerField()
    weight = models.IntegerField()
    # there are a lot more properties ... 

class Group(models.Model):
    name = models.CharField()
    summary = JSONField()

    def save(self, *args, **kwargs):
        self.summary = _update_summary()
        super().save(*args, **kwargs)
    def _update_summary(self):
        return calculate_group_summary(self.summary)

# this helper function is located in a helper file
def calculate_group_summary(group_summary):
   """calculates group.summary data based on group.users"""
   # retrieve users, iterate over them, calculate data and store results in group_summary object
   return group_summary

对于上述型号,我有这个工厂:
# factories.py
class UserFactory(factory.DjangoModelFactory):
    class Meta:
        model = User

    name = factory.Sequence(lambda n: "user name %d" % n)
    age = randint(10, 90))
    weight = randint(30, 110))

class GroupFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = Group

    name = factory.Sequence(lambda n: "group name %d" % n)
    summary = {
        "users": [34, 66, 76],
        "age": {
            "mean": 0,
            "max": 0,
            "min": 0,
        },
        "weight": {
            "mean": 0,
            "max": 0,
            "min": 0,
        } 
    }

特殊性是我在 group.save() 上更新字段 group.summary 中的 JSON 数据。
注意:我不喜欢将其移至 post_save 信号,因为我想避免“双重”保存(我有创建/修订字段)。

所以当我使用 GroupFactory() 时,我必须让“用户”就位。

我在看后生成 Hook https://factoryboy.readthedocs.io/en/latest/reference.html#post-generation-hooks ,但我需要“预生成钩子(Hook)”。

是否有在创建 GroupFactory 之前生成用户数据的“最佳实践”(无需在测试用例中手动创建它们)?类似于“后一代钩子(Hook)”但“前”的东西? :|

最佳答案

尝试使用 _create()钩。像这样的东西:

class GroupFactory():
    ...


    @classmethod
    def _create(cls, model_class, *args, **kwargs):
        # Create the prerequisite data here. 
        # Use `UserFactory.create_batch(n)` if multiple instances are needed.
        user = UserFactory()

        group = model_class(*args, **kwargs)

        # Update other fields here if needed.
        group.foo = bar

        # Required operation.
        group.save()

        return group

引用:https://factoryboy.readthedocs.io/en/latest/reference.html#factory.Factory._create

关于python - 工厂男孩 - 如何创建工厂所需的数据(预生成 Hook ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54530266/

相关文章:

python - 用 Django 打开 ID

unit-testing - 如何使用单元测试来测试资源 Controller

objective-c - Objective-C 中类扩展的正确文件命名约定是什么?

python - await 如何在协程链接期间将控制权交还给事件循环?

python - 一站式管理

python - 使用 yum 安装 python-devel

python - django 在 ubuntu 中找不到数据库

angular - 测试ActivatedRoute.paramMap而不模拟路由器

python - 如何用dask执行多线程 `merge()`?如何通过 qsub 使用多核?

python - 从文件中删除特定的 JSON 对象,然后存储该文件