Search code examples
djangoabstractfixturesfactory-boy

How can I instantiate a Subclass of my Django AbstractBaseUser with FactoryBoy


I've been trying to use Factory Boy to make my writing of Unit Tests easier. However, the library is being less than cooperative when I'm trying to instantiate instances of my custom user class

The custom class inherits from AbstractBaseUser and PermissionsMixin, as per the guide of enter link description here.

Everyime I try to instantiate this class like so:

class LogoutTests(TestCase):

    def setUp(self):
        self.employee_password = "foo"
        self.manager_password = "bar"
        self.test_employee_user = EmployeeFactory.create(self.employee_password)
        self.test_manager_user = ManagerFactory.create(self.manager_password)

However, I keep getting this error message:

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

I have tested this with other models and only my custom User model generates this error due to it possibly inheriting from AbstractBaseUser. Any help with this?

For reference, my custom user class:

class Employee(AbstractBaseUser, PermissionsMixin):

    class Meta:
        abstract = False

    first_name = models.CharField(max_length=250, default="Thibault", blank=False)
    last_name = models.CharField(max_length=250, default="Dupont", blank=False)
    email = models.EmailField(max_length=250, unique=True, blank=False, null=True)
    employee_number = models.OneToOneField(EmployeeNumber)
    is_manager = models.BooleanField(default=False, blank=False)
    is_employed = models.BooleanField(default=True, blank=False)
    is_active = models.BooleanField(default=False)

    objects = EmployeeManager()
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    def __str__(self):
        return self.get_full_name()

    def get_short_name(self):
        return '{0}. {1}'.format(self.first_name[0], self.last_name)

    def get_full_name(self):
        return '{0} {1}'.format(self.first_name, self.last_name)

    def email_user(self, subject, message, from_email=None, **kwargs):
        send_mail(subject, message, from_email, [self.email], **kwargs

Solution

  • The message says that you haven't told what model should be created by ManagerFactory: ManagerFactory.Meta.model is not set.

    The factory should look like this:

    import factory
    import factory.django
    
    from myapp import models
    
    class ManagerFactory(factory.django.DjangoModelFactory):
        class Meta:
            model = models.Manager
    
        # Your declarations here