I'm using Factory Boy for testing a Django project and I've run into an issue while testing a model for which I've overridden the save method.
The model:
class Profile(models.Model):
active = models.BooleanField()
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE,
related_name='profiles')
department = models.ForeignKey(Department, null=True, blank=True)
category_at_start = models.ForeignKey(Category)
role = models.ForeignKey(Role)
series = models.ForeignKey(Series, null=True, blank=True)
status = models.ForeignKey('Status', Status)
def save(self, *args, **kwargs):
super(Profile, self).save(*args, **kwargs)
active_roles = []
active_status = []
for profile in Profile.objects.filter(user=self.user):
if profile.active:
active_roles.append(profile.role.code)
active_status.append(profile.status.name)
self.user.current_role = '/'.join(set(active_roles))
if 'Training' in active_status:
self.user.current_status = 'Training'
elif 'Certified' in active_status:
self.user.current_status = 'Certified'
else:
self.user.current_status = '/'.join(set(active_status))
self.user.save()
super(Profile, self).save(*args, **kwargs) ### <-- seems to be the issue.
The factory:
class ProfileFactory(f.django.DjangoModelFactory):
class Meta:
model = models.Profile
active = f.Faker('boolean')
user = f.SubFactory(UserFactory)
department = f.SubFactory(DepartmentFactory)
category_at_start = f.SubFactory(CategoryFactory)
role = f.SubFactory(RoleFactory)
series = f.SubFactory(SeriesFactory)
status = f.SubFactory(StatusFactory)
The test:
class ProfileTest(TestCase):
def test_profile_creation(self):
o = factories.ProfileFactory()
self.assertTrue(isinstance(o, models.Profile))
When I run the tests, I get the following error:
django.db.utils.IntegrityError: UNIQUE constraint failed: simtrack_profile.id
If I comment out the last last/second 'super' statement in the Profile save method the tests pass. I wonder if this statement is trying to create the profile again with the same ID? I've tried various things such as specifying in the Meta class django_get_or_create and various hacked versions of overriding the _generation method for the Factory with disconnecting and connecting the post generation save, but I can't get it to work.
In the meantime, I've set the strategy to build but obviously that won't test my save method.
Any help greatly appreciated.
J.