You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在pytest中向FactoryBoy嵌套RelatedFactories传递参数?

解决FactoryBoy多层关联工厂的参数传递问题

完全可以实现你的需求,用FactoryBoy的Class Params作为状态载体是合理方案,适配你这种多层关联、多依赖工厂的场景。下面是具体实现方式:

修改后的工厂代码

import factory
from .models import FruitBasket, Apple, Seed, Skin

class FruitBasketFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = FruitBasket

    # 定义顶层控制参数,默认关闭PinkLady类型
    class Params:
        apple_type_is_PinkLady = False

    # 将顶层参数传递给AppleFactory
    apple = factory.RelatedFactory(
        "your_app.factories.AppleFactory",
        factory_related_name="fruit_basket",
        apple_type_is_PinkLady=factory.SelfAttribute("..apple_type_is_PinkLady"),
    )

class AppleFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = Apple

    fruit_basket = None

    # 接收上层传递的参数
    class Params:
        apple_type_is_PinkLady = False

    # 将参数传递给SeedFactory和SkinFactory
    seed = factory.RelatedFactory(
        "your_app.factories.SeedFactory",
        factory_related_name="apple",
        apple_type_is_PinkLady=factory.SelfAttribute("..apple_type_is_PinkLady"),
    )
    skin = factory.RelatedFactory(
        "your_app.factories.SkinFactory",
        factory_related_name="apple",
        apple_type_is_PinkLady=factory.SelfAttribute("..apple_type_is_PinkLady"),
    )

class SeedFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = Seed

    apple = None

    # 接收参数并设置默认属性
    class Params:
        apple_type_is_PinkLady = False

    # 根据参数动态覆盖属性值
    num_seeds = factory.Maybe(
        "apple_type_is_PinkLady",
        yes=5,
        no=10,
    )
    seed_color = factory.Maybe(
        "apple_type_is_PinkLady",
        yes="brown",
        no="black",
    )

class SkinFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = Skin

    apple = None

    class Params:
        apple_type_is_PinkLady = False

    skin_color = factory.Maybe(
        "apple_type_is_PinkLady",
        yes="green",
        no="red",
    )

关键实现细节

  • 参数传递链路:通过factory.SelfAttribute("..apple_type_is_PinkLady")实现跨层级参数传递,..表示向上访问父级工厂的属性。
  • 动态属性覆盖:使用factory.Maybe根据参数值切换属性默认值,逻辑清晰且易于扩展。
  • 扩展性:如果中间工厂有5-10个关联工厂,只需在中间工厂的每个RelatedFactory中传递该参数,子工厂按需添加Params和Maybe逻辑即可,不会产生冗余代码。

使用方式

在测试中直接调用顶层工厂并传入参数:

# 创建普通果篮
normal_basket = FruitBasketFactory()
assert normal_basket.apple.seed.num_seeds == 10
assert normal_basket.apple.seed.seed_color == "black"
assert normal_basket.apple.skin.skin_color == "red"

# 创建PinkLady类型的果篮
pink_lady_basket = FruitBasketFactory(apple_type_is_PinkLady=True)
assert pink_lady_basket.apple.seed.num_seeds == 5
assert pink_lady_basket.apple.seed.seed_color == "brown"
assert pink_lady_basket.apple.skin.skin_color == "green"

内容的提问来源于stack exchange,提问作者chillingfox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 20:22:49