Django的self.client.login(…)在unit testing中不起作用

我用两种方法为我的unit testing创​​build了用户:

1)创build一个“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。

我已经validation了这个信息正确地被一次又一次地加载到testing数据库中。 我可以使用User.objects.get获取User对象。 我可以使用'check_password'validation密码是否正确。 用户处于活动状态。

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

我的unit testing中的login代码如下所示:

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

谢谢。

该代码不起作用:

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

为什么不起作用?

在上面的代码片段中,创buildUser时,实际的密码哈希设置为12345 。 当客户端调用login方法时, password参数12345的值通过散列函数传递,导致类似的情况

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

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

解决scheme

正确的做法是调用set_password函数,该函数将给定的string传递给散列函数,并将结果存储在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') 

更简单的方法是在Django 1.9中使用force_login ,New。 http://django.readthedocs.io/en/1.9.x/topics/testing/tools.html#django.test.Client.force_login force_login(user,backend = None)

例如:

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

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

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

你可以检查下面,

 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) 

这个testing案例为我工作。

如果还有人继续这样做,我认为属性'is_staff'和'is_active'应该保持为True才能成功login……

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