测试用户是否已成功登录

时间:2011-04-14 09:16:27

标签: django

如何在提交注册表单后测试用户是否已登录?

我尝试了以下操作,但在我将登录逻辑添加到注册视图之前,它返回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

6 个答案:

答案 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。如果Falserequest.user.is_authenticated()的实例,request.user方法始终返回AnonymousUser,则会为is_authenticated()返回False。 在测试时,您可以查看response.context['request'].user.is_authenticated()

您还可以尝试访问需要登录的测试中的其他页面,并查看response.status是否返回200302(从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更简单。