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

时间:2010-04-11 23:17:24

标签: django unit-testing django-authentication django-testing

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

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') 

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

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

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

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

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

感谢。

6 个答案:

答案 0 :(得分:88)

不起作用的代码:

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')

答案 1 :(得分:33)

更简单的方法是在Django 1.9中使用force_login,new。

force_login(user, backend=None)

例如:

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

答案 2 :(得分:5)

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

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

答案 3 :(得分:3)

你可以像下面一样检查,

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)

这个测试用例对我有用。

答案 4 :(得分: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)

答案 5 :(得分:-3)

如果有人仍然关注此事,我认为属性'is_staff'和'is_active'应该保持为True以便成功登录......

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