pytest-factoryboy
pytest-factoryboy copied to clipboard
Factories behave differently as fixtures when there's a related model?
(I really have no clue what to title this ticket.)
What I'm seeing though is that when I register a factory, the model fixture behaves differently when it's called vs. just a bare invocation of the factory.
Here's the code for some Tags I'm trying to test, which have a related Type:
# factories.py
class TagTypeFactory(factory.django.DjangoModelFactory):
name = factory.Sequence(lambda n: "type_%d" % n)
unique = factory.Faker("boolean")
color = factory.Faker("hex_color")
created_by = factory.SubFactory(UserFactory)
updated_by = factory.LazyAttribute(lambda obj: obj.created_by)
class Meta:
model = "common.TagType"
django_get_or_create = ("name",)
class TagFactory(factory.django.DjangoModelFactory):
name = factory.Sequence(lambda n: "tag_%d" % n)
description = factory.Faker("bs")
type = factory.SubFactory(
factory=TagTypeFactory,
name=TagType.MISC_NAME,
)
created_by = factory.SubFactory(UserFactory)
updated_by = factory.LazyAttribute(lambda obj: obj.created_by)
slug = factory.LazyAttribute(lambda obj: f"{obj.type.name}:{obj.name}".lower())
class Meta:
model = "common.Tag"
django_get_or_create = ("name",)
The idea here is that the default name of TagType.MISC_NAME will be used for all tags, unless I need a different type. like so:
In [3]: TagFactory()
Out[3]: <Tag: tag_0 (miscellaneous)>
In [6]: TagTypeFactory()
Out[6]: <TagType[13] n:type_3: s:False, a:True>
In [7]: TagTypeFactory(name='service')
Out[7]: <TagType[3] n:service: s:True, a:True>
This works to lookup pre-populated tags because I'm using django_get_or_create on the factories so name arguments can be existing tags/types.
But when I register the TagFactory, and call the 'tag' fixture, from another fixture like so:
def fixture_user(tag) -> User:
logger.debug("Tag for user fixture: %r", tag)
I get a Tag with a different type than I'd expect:
DEBUG Tag for user fixture: <Tag: tag_1 (type_1)>