93

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

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

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

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

2)在setUp函数中使用'create_user'(尽管我宁愿将所有东西都保留在我的fixtures类中):

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

请注意,两种情况下的密码都是 simpson。

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

然而,self.client.login(username='homer', password='simpson') 总是失败。我很困惑为什么。我想我已经阅读了与此相关的每一个 Internet 讨论。有人可以帮忙吗?

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

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

谢谢。

4

6 回答 6

149

不起作用的代码:

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')
于 2015-10-23T04:11:45.970 回答
67

一种更简单的方法是使用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])
于 2016-09-28T09:07:12.830 回答
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)

这个测试用例对我有用。

于 2015-10-12T06:17:40.177 回答
5

检查是否django.contrib.sessions已添加,INSTALLED_APPS因为client.login()检查它是否存在,如果不是,则始终返回 false:

https://docs.djangoproject.com/es/1.9/topics/http/sessions/#enabling-sessions

于 2016-01-13T19:50:53.733 回答
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)
于 2019-08-22T05:57:07.467 回答
-4

如果还有人关注这个,我认为属性 'is_staff' 和 'is_active' 应该保持 True 才能成功登录......

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

于 2012-11-14T10:38:48.160 回答