如何在提交注册表单后测试用户是否已登录?
我尝试了以下操作,但在我将登录逻辑添加到注册视图之前,它返回True
。
def test_that_user_gets_logged_in(self):
response = self.client.post(reverse('auth-registration'),
{ 'username':'foo',
'password1':'bar',
'password2':'bar' } )
user = User.objects.get(username='foo')
assert user.is_authenticated()
正在测试的代码:
class RegistrationView(CreateView):
template_name = 'auth/registration.html'
form_class = UserCreationForm
success_url = '/'
def auth_login(self, request, username, password):
'''
Authenticate always needs to be called before login because it
adds which backend did the authentication which is required by login.
'''
user = authenticate(username=username, password=password)
login(request, user)
def form_valid(self, form):
'''
Overwrite form_valid to login.
'''
#save the user
response = super(RegistrationView, self).form_valid(form)
#Get the user creditials
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
#authenticate and login
self.auth_login(self.request, username, password)
return response
答案 0 :(得分:68)
这不是最好的答案。见https://stackoverflow.com/a/35871564/307511
Chronial已经给出了 关于如何在下面做出这个断言的一个很好的例子。他的回答 对于现在的代码来说比我好。
测试用户是否登录的最简单方法是测试Client对象:
self.assertIn('_auth_user_id', self.client.session)
您还可以检查特定用户是否已登录:
self.assertEqual(int(self.client.session['_auth_user_id']), user.pk)
作为附加信息,response.request
对象不是HttpRequest
对象;相反,它是一个普通的dict,其中包含有关实际请求的一些信息,因此它无论如何都不会有user
属性。
此外,测试response.context
对象并不安全,因为您没有上下文。
答案 1 :(得分:54)
您可以使用auth
模块的get_user
方法。它说它想要一个请求作为参数,但它只使用请求的session
属性。只是我们的Client
具有该属性。
from django.contrib import auth
user = auth.get_user(self.client)
assert user.is_authenticated()
答案 2 :(得分:9)
Django的TestClient有login method,如果用户成功登录则返回True。
答案 3 :(得分:5)
is_authenticated()
模型上的方法User
始终返回True
。如果False
是request.user.is_authenticated()
的实例,request.user
方法始终返回AnonymousUser
,则会为is_authenticated()
返回False
。
在测试时,您可以查看response.context['request'].user.is_authenticated()
。
您还可以尝试访问需要登录的测试中的其他页面,并查看response.status
是否返回200
或302
(从login_required
重定向)。
答案 4 :(得分:1)
您在哪里初始化self.client
?您的setUp
方法还有哪些内容?我有一个类似的测试,你的代码应该可以正常工作。我是这样做的:
from django.contrib.auth.models import User
from django.test import TestCase
from django.test.client import Client
class UserTestCase(TestCase):
def setUp(self):
self.client = Client()
def testLogin(self):
print User.objects.all() # returns []
response = self.client.post(reverse('auth-registration'),
{ 'username':'foo',
'password1':'bar',
'password2':'bar' } )
print User.objects.all() # returns one user
print User.objects.all()[0].is_authenticated() # returns True
修改强>
如果我注释掉我的登录逻辑,我在self.client.post(
后没有得到任何用户。如果您确实想要检查用户是否已通过身份验证,请使用self.client
访问需要用户身份验证的其他网址。继续上述内容,访问另一页:
response = self.client.get(reverse('another-page-which-requires-authentication'))
print response.status_code
上面应该返回200以确认用户已经过身份验证。除此之外,它将使用302代码重定向到登录页面。
答案 5 :(得分:0)
还有一种简洁的方法,使用wsgi_request
中的response
:
response = self.client.post('/signup', data)
assert response.wsgi_request.user.is_authenticated()
和@Chronial的方式也适用于wsgi_request
:
from django.contrib import auth
user = auth.get_user(response.wsgi_request)
assert user.is_authenticated()
因为response.wsgi_request
对象具有session
属性。
但是,我认为使用response.wsgi_request.user
更简单。