djangotestingdjango-rest-frameworkpytestfaker

How to create distinct items using FactoryBoy in Django Rest Framework


I have the following code.

#factories.py

fake: Faker = Faker()


class CollectionFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = Collection
        django_get_or_create = ('title', )

    title = fake.word(part_of_speech='noun')


class ProductFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = Product
        # django_get_or_create = ('title',)

    title = fake.word(part_of_speech='noun')
    slug = fake.slug()
    description = fake.text()
    unit_price = fake.pydecimal(max_value=1000, min_value=1, right_digits=2)
    inventory = fake.random_number(digits=4)
    last_update = fake.date_time_ad(start_datetime=datetime(1998, 1, 1, 1, 1, 1), end_datetime=datetime.now())
    # collection = CollectionFactory()
    collection = factory.SubFactory(CollectionFactory)

#test_product.py

@pytest.mark.django_db
class TestListProduct:

    def test_product1(self, api_client, product_factory):
        product_factory: ProductFactory = product_factory
        product_factory.create_batch(10)

        prods = Product.objects.all()  # Problem: all of these products have the same title
        cols = Collection.objects.all()
        assert Product.objects.count() == 1

But the problem is that when I am doing the test all of the products are identical, I need them to at least have different titles. How do I achieve this?


Solution

  • Your fake.word(part_of_speech='noun') is not a factory that produces nouns, but it generates a single noun that is then used.

    But you are probably also using the wrong faker: the Faker of the Faker package, not the one wrapped around it with the factory_boy:

    from factory.faker import Faker
    
    
    class ProductFactory(factory.django.DjangoModelFactory):
        class Meta:
            model = Product
    
        title = Faker('word', part_of_speech='noun')

    the same for all other uses of the Faker, like slug, description, etc.