python - Django - 测试 - @login_required 装饰器的问题

标签 python django unit-testing testing django-authentication

问题

更新:事实证明,这个问题与 @login_required 装饰器无关!

当我尝试测试用 @login_required 装饰的 View 时,我变得很挑剔。

我有一个测试实际上能够转到用 @login_required 装饰的 View (密码更改 View )。然而,不同的测试总是被重定向到登录。无论我尝试以哪种方式重写它,它都不会让我的测试用户通过,即使我让用户登录并事先断言 user.is_authenticated() 也是如此。

这是有问题的测试的相关片段:

# Log user in
self.client.login(username=user.username, password=user.password)
self.assertTrue(user.is_authenticated())

# Go to account_edit view
url = reverse('account_edit')
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'users/account_edit_form.html')

这不可避免地重定向到登录 View ,就好像用户没有登录一样。

我可以确认此行为并未反射(reflect)在应用程序的“正常”功能中;当我实际运行服务器然后导航到此 View 时,装饰器完全按照预期工作(即它允许在登录时访问,并重定向到登录 View )。

使用 Django 1.3.1。我正在使用 django-nose 的测试运行器,但我可以确认无论我使用哪个测试运行器都会发生此问题。

另外,我发现了几个以前的问题,但是建议的解决方案要么是旧版本的 Django 特有的,要么在这种情况下没有帮助(例如,参见 here)。

解决方案(结合两个好的答案)

对于这个问题,我收到了两个非常好的答案,它们都强调了我发布的代码片段中的重要疏忽。该问题与 @login_required 的行为无关,而是与 (a) 用户签名错误和 (b) 检查用户身份验证错误有关。

我很难选择接受哪个答案,但经过深思熟虑后,我决定接受 Konrad Hałas 的答案,因为它指出了我的关键疏忽,这是意外行为的根源。

尽管如此,如果我没有使用错误的测试线 self.assertTrue(user.is_authenticated()),我会更快地弄清楚这一点。因此,为了强调解决方案实际上分为两部分,这里是修复有问题的代码的两个步骤:

# Log user in *NOTE: Password needs to be raw (from Konrad's answer)
self.client.login(username=user.username, password="pass")
self.assertTrue(user.is_authenticated()) # <-- still not correct

断言行仍然有问题,因为有效用户总是满足 user.is_authenticated()。请参阅 Alasdair 的信息以了解此问题的解释。因此修复此代码的第二步是:

# Log user in *NOTE: Password needs to be raw (from Konrad's answer)
login_successful = self.client.login(username=user.username, password="pass")
self.assertTrue(login_successful) # Much better! (see Alasdair's answer)

最后,如果您需要使用 client.login(即测试登录表单)测试您的用户是否登录,这应该可行:

self.assertTrue(response.context['user'].is_authenticated())

最佳答案

user.password 是密码哈希。你不能用它登录。您需要使用原始密码:

self.client.login(username=user.username, password='<user password>')

关于python - Django - 测试 - @login_required 装饰器的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12166568/

相关文章:

Django Rest Framework 使用动态字段进行序列化

java - 是否有一种聪明的方法来单元测试 AspectJ 策略执行方面?

java - 是否可以对 JUnit 中的每个测试用例使用不同的@Before @After?

python - 如何使 python 脚本在有参数和无参数(默认参数)的情况下工作?

java - 从 Java 运行 Python 脚本

python - 使用 tensorflow.data.Dataset.from_generator 时出现 InvalidArgumentError

python - 使用字符串元组更新 Python 字典以设置(键,值)失败

python - group-by 输出中 DateTimeFields 的 Django 时间戳列表

python - 使用链接的 Django 模型快速计数

visual-studio-2010 - 如何在 Visual Studio 2010 中禁用对用户未处理的异常的中断?