Django factory_boy中的用户认证测试

7

当我尝试单元测试我的代码时,需要一个已经登录的用户。为了减少太多装置,我使用了django_factory_boy用户工厂,但生成的用户无法进行身份验证。

from django_factory_boy.auth import UserF
from django.contrib.auth import authenticate

user = UserF()
user.set_password('password')

那么authenticate(username = user.username,password ='password')返回None而不是用户。对此有什么想法?

3个回答

11

@Andrew-Magee的解决方案可行,但这里有一个在文档中描述的解决方案

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 = 'test@example.com'
    password = factory.PostGenerationMethodCall('set_password', 'password')

Django控制台 :

>>> from tests.factories import UserFactory
>>> from django.contrib.auth.models import check_password
>>> user = UserFactory()
>>> user.email
'test@example.com'
>>> check_password('password', user.password)
True

>>> user2 = UserFactory(username="SecondUserFactory", email='otheremail@example.com', password="ComplexPasswordMuchLonger!")
>>> user2.email
'otheremail@example.com'
>>> check_password('ComplexPasswordMuchLonger!', user2.password)
True

1
我也喜欢这个解决方案。它在 factory_boy文档 中有明确的说明。 - Merwan

9

另一种方法:

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%s@example.com" % n)
    username = factory.Sequence(lambda n: "email%s@example.com" % 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

4
你应该在调用 user.set_password() 后再调用 user.save(),因为 set_password 只是设置了数据,而不会保存用户。

谢谢!我终于找到了解决方案,但由于声望不够,无法回复自己。 - sebastibe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接