Search code examples
pythondjangofactory-boy

Django / FactoryBoy - unable to generate instance for abstract models


I am writing tests for a Django application and I am currently running into the following problem:

I have this (abstract) model:


class HeroContent(models.Model):
    title = models.CharField(
        max_length=100, blank=True, null=True,
        default=None)
    subtitle = models.CharField(
        max_length=255, blank=True, null=True,
        default=None)

    class Meta:
        abstract = True

For which I created the following factory:


class HeroContentFactory(factory.DjangoModelFactory):

    class Meta:
        model = HeroContent
        abstract = True

    title = factory.Faker('company')
    subtitle = factory.Faker('company')

I consulted the documentation on how to handle abstract models, but when I run the following test:

class HeroContentFactoryTest(TestCase):

    def test_init(self):
        hero_content = HeroContentFactory()

The following error gets raised:

FactoryError: Cannot generate instances of abstract factory HeroContentFactory; Ensure HeroContentFactory.Meta.model is set and HeroContentFactory.Meta.abstract is either not set or False.

But this seems to go directly against the course recommended in the official documentation, which states that when

If a DjangoModelFactory relates to an abstract model, be sure to declare the DjangoModelFactory as abstract

Removing the abstract = True setting from the Factory

Raises the following error:

AttributeError: 'NoneType' object has no attribute 'create'

calling .create on a abstract model should fail ofcourse, but now I am wondering what would be the proper way to test these kind of models using factory - especially sinds the course suggested in the documentation is not working for me.

Does anyone know what I am doing wrong?


Solution

  • You need to inherit from HeroContentFactory into HeroContentConcreteFactory, which will be tied to a subclass of HeroContent, which will be a concrete model. You can't instantiate from an abstract model nor abstract factory.