factoryboy 覆盖 lazy_attribute 的属性

factoryboy override attribute of lazy_attribute

我有一些嵌套的 google.proto.message 对象,并且在使用 factoryboy 制作测试数据时试图覆盖父模型深处的属性。一些子消息是使用 lazy_attribute 创建的,其中包含使用其他对象填充它们的逻辑。 我已经使用 attrs 模型通过一个更简单的示例重现了我在 factoryboy 中遇到的问题。

class BookFactory(factory.Factory):
  class Meta:
    model = models.Book

  class Params:
    num_pages = 10

  @factory.lazy_attribute
  def pages(self):
    return PageFactory.build_batch(self.num_pages)


book = BookFactory.build(
  num_pages=3,
  pages__0__content='mypage0',
)

# This fails. How do I override pages[0].content with a BookFactory attribute?
assert book.pages[0].content == 'mypage0'

我有一个 运行 失败的例子 https://repl.it/@TomGoBravo/lazyattributesubfactory

感谢您的任何建议!

最好的方法是将 SubFactory 包裹在 factory.List 中,但您将无法调整所述列表的长度:

class BookFactory(factory.Factory):
    class Meta:
        model = models.Book

    pages = factory.List([
        factory.SubFactory(PageFactory),
        factory.SubFactory(PageFactory),
        factory.SubFactory(PageFactory),
    ])

否则,您必须实施(并贡献!)某种形式的 SubFactoryList,类似于现有的 RelatedFactoryList

您可以使用 post_generation 方法来控制创建的项目数以及基础模型的属性。

class BookFactory(factory.Factory):
  class Meta:
    model = models.Book

@factory.post_generation
def pages(self, create, extracted, **kwargs):
    if not create:
        return
    num_pages = kwargs.get('num_pages', 0)
    if num_pages > 0:
        book.pages = <---code goes here--->

book = BookFactory.build(
  pages__num_pages=3,
  pages__0__content='mypage0',
)