Django的self.client.login(...)在单元测试中不起作用


83

我已经通过两种方式为我的单元测试创​​建了用户:

1)为“ auth.user”创建一个大致如下的灯具:

    { 
        "pk": 1, 
        "model": "auth.user", 
        "fields": { 
            "username": "homer", 
            "is_active": 1, 
            "password": 
"sha1$72cd3$4935449e2cd7efb8b3723fb9958fe3bb100a30f2", 
            ... 
        } 
    }

我省略了看似不重要的部分。

2)在setUp函数中使用“ create_user”(尽管我宁愿将所有内容都保存在我的装置类中):

def setUp(self): 
       User.objects.create_user('homer', 'ho...@simpson.net', 'simpson') 

请注意,两种情况下的密码均为辛普森。

我已验证该信息一次又一次正确地加载到测试数据库中。我可以使用User.objects.get来获取User对象。我可以使用“ check_password”验证密码是否正确。用户处于活动状态。

但是,self.client.login(username ='homer',password ='simpson')总是失败。我对为什么感到困惑。我想我已经阅读了与此相关的每个互联网讨论。有人可以帮忙吗?

我的单元测试中的登录代码如下所示:

    login = self.client.login(username='homer', password='simpson') 
    self.assertTrue(login) 

谢谢。


1
您收到的错误消息是什么?
zs2020 '04

测试用例在“ self.assertTrue(login)”行上失败;login()函数返回False。
thebossman 2010年

1
我基本上复制并粘贴了您的第二个版本,它可以在Django 1.3上运行。您可以发布包括导入内容在内的整个代码吗?
Liorsion 2011年

这已经埋没在我不再访问的代码库中。如果我遇到问题,我一定会跟进,但据记录,是使用早期版本的Django的;我认为是1.0.2。
thebossman 2011年

Answers:


120

无效的代码:

from django.contrib.auth.models import User
from django.test import Client

user = User.objects.create(username='testuser', password='12345')

c = Client()
logged_in = c.login(username='testuser', password='12345')

为什么不起作用?

在上面的代码段中,User创建时,实际的密码哈希设置为12345。当客户端调用该login方法时,password参数的值12345将通过哈希函数传递,结果是

hash('12345') = 'adkfh5lkad438....'

然后将其与存储在数据库中的哈希进行比较,并且拒绝客户端访问,因为 'adkfh5lkad438....' != '12345'

解决方案

正确的做法是调用set_password函数,该函数通过哈希函数传递给定的字符串并将结果存储在中User.password

另外,调用后,set_password我们必须将更新的User对象保存到数据库中:

user = User.objects.create(username='testuser')
user.set_password('12345')
user.save()

c = Client()
logged_in = c.login(username='testuser', password='12345')

44
您的使用User.objects.create_superuser()User.objects.create_user()执行此set_password()调用完全相同。
vdboor

当您登录一个人时如何
岩石浣熊

添加到@vdboor注释:请注意,由于Django 1.4还User.objects.get_or_create()执行了必需的set_password()调用
引发了

51

一种更简单的方法是使用force_loginDjango 1.9中的新增功能。

force_login(user, backend=None)

例如:

class LoginView(TestCase):
    def setUp(self):
        self.client.force_login(User.objects.get_or_create(username='testuser')[0])

5

你能像下面这样检查吗?

from django.test import TransactionTestCase, Client

class UserHistoryTest(TransactionTestCase):
    self.user = User.objects.create(username='admin', password='pass@123', email='admin@admin.com')
    self.client = Client() # May be you have missed this line

    def test_history(self):
        self.client.login(username=self.user.username, password='pass@123')
        # get_history function having login_required decorator
        response = self.client.post(reverse('get_history'), {'user_id': self.user.id})
        self.assertEqual(response.status_code, 200)

这个测试用例对我有用。



0
from django.test import TestCase
from django.contrib.auth.models import User
from django.test import Client
class MyProfile(TestCase):
    @classmethod
    def setUpClass(self):
        self.username = 'dummy' + data + '@gmail.com'
        self.password = 'Dummy@123'
        user = User.objects.create(username=self.username)
        user.set_password(self.password)
        user.save()
        c = Client()
        self.client_object = c.login(username=self.username, password=self.password)
        self.content_type = "application/json"
        response = self.client_object.post('/api/my-profile/', content_type=self.content_type)

-3

如果仍然有人遵循此原则,我认为应将属性“ is_staff”和“ is_active”保持为True才能成功登录……

self.user = User.objects.create(username='testuser',password='pwd',is_active=1,is_staff=1)


4
这才起作用........... self.user = User.objects.create(用户名='testuser',密码='12345',is_active = True,is_staff = True,is_superuser = True)self。 user.set_password('hello')self.user.save()user = authenticate(用户名='testuser',password ='hello')login = self.c.login(用户名='testuser',password ='hello' )self.assertTrue(登录)
Arindam Roychowdhury 2012年

这与is_staff定义授予一般访问管理面板的权限无关。如您所见,初始过帐中的数据已经存在is_active = 1,这也是的默认值User.objects.create()
jnns 2013年

1
@arindamroychowdhury -哇,这实际工作。(你的意见,这是)
理查德·德维特

1
这可能是版本问题,但我不得不注释掉您的身份验证电话。除此之外,您的评论就像冠军!根据进一步的测试思想,我发现is_active,is_superuser和is_staff都是不必要的。这样做的原因是对set_password的调用。
dolphus333 '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.