Reputation: 587
When trying to unit test some part of my code, I need a user to be logged in. For reducing the number of fixtures I am using django_factory_boy User factory but the User generated is unable to authenticate.
from django_factory_boy.auth import UserF
from django.contrib.auth import authenticate
user = UserF()
user.set_password('password')
then authenticate(username=user.username, password='password')
return None
instead of the User. Any ideas about what is missing here?
Upvotes: 7
Views: 2631
Reputation: 14801
@Andrew-Magee solution works, but here the solution describe in the doc:
import factory
from django.contrib.auth.models import User
#or
#from somewhere import CustomUser as User
class UserFactory(factory.DjangoModelFactory):
FACTORY_FOR = User
username = 'UserFactory'
email = '[email protected]'
password = factory.PostGenerationMethodCall('set_password', 'password')
Django console :
>>> from tests.factories import UserFactory
>>> from django.contrib.auth.models import check_password
>>> user = UserFactory()
>>> user.email
'[email protected]'
>>> check_password('password', user.password)
True
>>> user2 = UserFactory(username="SecondUserFactory", email='[email protected]', password="ComplexPasswordMuchLonger!")
>>> user2.email
'[email protected]'
>>> check_password('ComplexPasswordMuchLonger!', user2.password)
True
Upvotes: 11
Reputation: 6684
Another way to do it:
import factory
from django.contrib.auth.hashers import make_password
from somewhere import YourUserModel
class UserF(factory.django.DjangoModelFactory):
FACTORY_FOR = YourUserModel
first_name = factory.Sequence(lambda n: "First%s" % n)
last_name = factory.Sequence(lambda n: "Last%s" % n)
email = factory.Sequence(lambda n: "email%[email protected]" % n)
username = factory.Sequence(lambda n: "email%[email protected]" % n)
password = make_password("password")
is_staff = False
>>> u = UserF.create()
>>> u.check_password("password")
True
>>> p = UserF.create(password=make_password("password2"))
>>> p.check_password("password2")
True
Upvotes: 9
Reputation: 5841
You should call user.save()
after user.set_password()
because set_password
itself does not save the user, only sets the data.
Upvotes: 5