Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django-测试-需要@login\u装饰程序时出现问题 问题_Python_Django_Unit Testing_Testing_Django Authentication - Fatal编程技术网

Python Django-测试-需要@login\u装饰程序时出现问题 问题

Python Django-测试-需要@login\u装饰程序时出现问题 问题,python,django,unit-testing,testing,django-authentication,Python,Django,Unit Testing,Testing,Django Authentication,更新:事实证明,这个问题与所需的@login\u装饰程序几乎没有关系 当我尝试测试用@login\u required修饰的视图时,我的行为越来越挑剔 我有一个测试,实际上可以进入一个用@login\u required装饰的视图(密码更改视图)。然而,不同的测试总是被重定向到登录。无论我尝试以何种方式重新编写它,它都不会让我的测试用户通过,即使我将用户登录并声明user.is\u authenticated() 以下是出现问题的测试的相关片段: # Log user in self.clien

更新:事实证明,这个问题与所需的
@login\u
装饰程序几乎没有关系

当我尝试测试用
@login\u required
修饰的视图时,我的行为越来越挑剔

我有一个测试,实际上可以进入一个用
@login\u required
装饰的视图(密码更改视图)。然而,不同的测试总是被重定向到登录。无论我尝试以何种方式重新编写它,它都不会让我的测试用户通过,即使我将用户登录并声明
user.is\u 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')
这不可避免地会重定向到登录视图,就好像用户没有登录一样

我可以确认,这种行为并没有反映在应用程序的“正常”功能中;当我实际运行服务器并导航到此视图时,decorator完全按照预期工作(即,它允许登录时进行访问,并重定向到登录视图)

使用Django 1.3.1。我正在使用来自django nose的testrunner,但我可以确认,无论我使用哪种testrunner,都会发生此问题

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

解决方案(结合两个好答案) 对于这个问题,我收到了两个非常好的答案,这两个答案都突出了我发布的片段中的重要疏忽。这个问题与
@login\u required
的行为无关,而是与(a)错误地为用户签名和(b)错误地检查用户身份验证有关

我很难选择接受哪一个答案,但经过一点思考,我决定接受康拉德·哈阿斯的答案,因为它指出了我这方面的关键疏忽,这是意外行为的根源

尽管如此,如果我没有使用错误的测试行
self.assertTrue(user.is\u 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
最后,如果您需要测试您的用户是否在未使用
client.login
(即测试登录表单)的情况下登录,这应该可以:

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

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

self.client.login(username=user.username, password='<user password>')
self.client.login(用户名=user.username,密码=“”)

这里的问题是,对于
用户
实例,该方法总是返回
True

在模板或视图中,它可能很有用-如果
request.user.is_authenticated()
True
,那么您有一个真实的用户,而不是
匿名用户
,并且可以相应地继续。但是,如果您从一个
用户
对象开始,就像您所做的那样,那么
是经过身份验证的()
可能会令人困惑

您可以检查测试客户机方法的返回值,以测试它是否成功

login_successful = c.login(username='fred', password='secret')
self.assertTrue(login_successful)

噢。太明显了!我也知道。(但我想还不够好。)所以我想我不能使用我一直使用的方法——从(测试)数据库中随机抓取一个用户并使用该用户的凭据运行测试。我只需要使用预先知道密码的用户,或者继续使用这种方法,但添加一个额外的步骤(即使用
user.set_password()
,以便我可以将密码更改为已知密码,只是为了运行测试)。是的,您不能。小OT:也许试试——这是比django fixtures更好的解决方案。这里你有一个例子,如何感谢要点。我觉得它很有用。这也很有用。这会让我更早地意识到这个问题。你的答案和康拉德的答案都是对的!我目前正在整合我从这两方面学到的知识,我将相应地更新我的问题,然后很快接受答案。这同样有效:self.assertTrue(response.context['user'].is_authenticated())--也就是说,如果登录失败,它将不起作用。如果您测试登录表单本身,这将非常有用。
login_successful = c.login(username='fred', password='secret')
self.assertTrue(login_successful)