To pass result of calling UserFactory
to AccountFactory
you should use factory_related_name
(docs)
Code above works next way:
AccountFactory
for instantiating needs SubFactory(UserFactory)
.
UserFactory
instantiates User.
UserFactory
after instantiating calls RelatedFactory(AccountFactory)
- Recursion,.. that is broken due to unique username constraint (you probably want to generate usernames via
FuzzyText
or Sequence
)
So you need write UserFactory
like this:
class UserFactory(factory.django.DjangoModelFactory):
account = factory.RelatedFactory(AccountFactory, factory_related_name='user')
username = factory.Sequence(lambda a: 'email%04d@somedomain.com' % a)
# rest of code
But you can still experience issues with already written tests. Imagine you have in tests places like next:
user = UserFactory()
account = Account(user=user)
Then adding RelatedFactory
will break tests. If you haven't lots of tests and contributors in your project, you could rewrite them. But if not, it is not an option. Here is how it could be handled:
class UserFactory(factory.django.DjangoModelFactory):
class Params:
generate_account = factory.Trait(
account=factory.RelatedFactory(AccountFactory, factory_related_name='user')
)
Then code above won't be broken, because default call of UserFactory
won't instantiate AccountFactory
. To instantiate user with account:
user_with_account = UserFactory(generate_account=True)