Search code examples
pythondjangounit-testingfactory-boy

Django factories for unit test: "Cannot assign "'1'": "User.group" must be a "Brand" instance."


I'm getting an error when I run my unit test for my user_profile/model.py: "Cannot assign "'1'": "User.group" must be a "Brand" instance."

I believe this error is because, in my factories for my unit test (factories.py), I'm not correctly assigning group when I'm creating an instance of UserFactory(). I thing group should map to the Brand class/factory but I'm not sure how to do this..

this is my user_profile/model.py:

class Brand(models.Model):

    name = models.CharField(max_length=20)

    def __unicode__(self):
        return self.name


class User(AbstractBaseUser, PermissionsMixin):

    username = models.CharField(
        'username',
        max_length=50,
        unique=True,
        db_index=True
    )
    email = models.EmailField('email address', unique=True)
    group = models.ForeignKey(Brand, null=True, blank=True)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    is_approved = models.BooleanField(default=True)

and in my user_profile/test/factories.py:

from user_profile.models import User, Brand

class UserFactory(factory.django.DjangoModelFactory):

    class Meta:

        model = User
        django_get_or_create = (
            'username',
            'email',
            'password',
            'is_approved',
            'is_active',
            'is_staff',
            'is_admin',
            'group'
        )


class BrandFactory(factory.django.DjangoModelFactory):

    class Meta:

        model = Brand
        django_get_or_create = ('name',)

BrandFactory(name='BRAND1')
BrandFactory(name='BRAND2')
BrandFactory(name='BRAND3')
BrandFactory(name='BRAND4')


UserFactory(
    username='[email protected]',
    email='[email protected]',
    password=12345,
    is_approved=True,
    is_active=True,
    is_staff=True,
    is_admin=True,
    group="1" <--- HOW DO I MAP THIS TO THE 'BRAND1' FACTORY/CLASS?!
)

UserFactory(
    username='[email protected]',
    email='[email protected]',
    password=12345,
    is_approved=True,
    is_active=True,
    is_staff=True,
    is_admin=True,
    group="2"  <--- HOW DO I MAP THIS TO THE 'BRAND2' FACTORY/CLASS?!
)

Solution

  • You have to assign the return value of BrandFactory to something. For example

    b1 = BrandFactory(name='BRAND1')
    b2 = BrandFactory(name='BRAND2')
    

    and then you use the reference to the model instance in your constructor

    UserFactory(
        username='[email protected]',
        email='[email protected]',
        password=12345,
        is_approved=True,
        is_active=True,
        is_staff=True,
        is_admin=True,
        group=b1
    )
    
    UserFactory(
        username='[email protected]',
        email='[email protected]',
        password=12345,
        is_approved=True,
        is_active=True,
        is_staff=True,
        is_admin=True,
        group=b2
    )