10

Is it possible to use Traits (or anything else in Factory Boy) to trigger the creation of other factory objects? For example: In a User-Purchase-Product situation, I want to create a user and inform that this user has a product purchased with something simple like that:

UserFactory.create(with_purchased_product=True)

Because it feels like too much trouble to call UserFactory, ProductFactory and PurchaseFactory, then crate the relationship between them. There has to be a simpler way to do that.

Any help would be appreciated.

1
  • 2
    Is the Purchase object a foreign key to the User? If so, you could set up a subfactory on PurchaseFactory to create a user and a product. factoryboy.readthedocs.io/en/latest/… Commented Nov 21, 2017 at 18:19

1 Answer 1

8

First, I'll be honest with you: I do not know if this is the best answer or if it follows the good practices of python.

Anyway, the solution that I found for this kind of scenario was to use post_generation.

import factory


class UserFactory(factory.DjangoModelFactory):
    class Meta:
        model = User

    name = factory.Faker('name'))

    @factory.post_generation
    def with_purchased_products(self, create, extracted, **kwargs):
        if extracted is not None:
            PurchaseFactory.create(user=self, with_products=extracted)


class PurchaseFactory(factory.DjangoModelFactory):
    class Meta:
        model = Purchase

    user = factory.SubFactory(UserFactory)

    @factory.post_generation
    def with_products(self, create, extracted, **kwargs):
        if extracted is not None:
            ProductFactory.create_batch(extracted, purchase=self)


class ProductFactory(factory.DjangoModelFactory):
    class Meta:
       model = Product

    purchase = factory.SubFactory(PurchaseFactory)

To make this work you just need to:

UserFactory.create(with_purchased_products=10)

And this is just a article that is helping learn more about Django tests with fakes & factories. Maybe can help you too.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.