Проверьте, что пользователь успешно вошел в систему - PullRequest
51 голосов
/ 14 апреля 2011

Как я могу проверить, что пользователь вошел в систему после отправки регистрационной формы?

Я попробовал следующее, но оно возвращает 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 ]

69 голосов
/ 16 мая 2011

Это не лучший ответ .См. https://stackoverflow.com/a/35871564/307511

Chronial дал отличный пример того, как сделать это утверждение ниже.Его ответ лучше моего на сегодняшний день.


Самый простой способ проверить, вошел ли пользователь в систему, - это проверить объект Client:

self.assertIn('_auth_user_id', self.client.session)

Youтакже может проверить, зарегистрирован ли конкретный пользователь:

self.assertEqual(int(self.client.session['_auth_user_id']), user.pk)

В качестве дополнительной информации объект response.request не является объектом HttpRequest;вместо этого это обычный диктат с некоторой информацией о текущем запросе, поэтому у него все равно не будет атрибута user.

Кроме того, тестирование объекта response.context небезопасно, потому что вы не всегдаиметь контекст.

59 голосов
/ 08 марта 2016

Вы можете использовать метод get_user модуля auth.Он говорит, что хочет запрос в качестве параметра, но он всегда использует только атрибут session запроса.И бывает, что наш Client имеет этот атрибут.

from django.contrib import auth
user = auth.get_user(self.client)
assert user.is_authenticated()
9 голосов
/ 14 мая 2012

TestClient Django имеет метод входа , который возвращает True, если пользователь успешно вошел в систему.

5 голосов
/ 14 апреля 2011

Метод 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).

1 голос
/ 14 апреля 2011

Где вы инициализируете свой 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

EDIT

Если я закомментирую логику входа в систему, я не получу пользователя после self.client.post(. Если вы действительно хотите проверить, прошел ли пользователь аутентификацию, используйте self.client для доступа к другому URL, который требует аутентификации пользователя. Продолжая описанное выше, перейдите на другую страницу:

response = self.client.get(reverse('another-page-which-requires-authentication'))
print response.status_code

Выше должно возвращаться 200, чтобы подтвердить, что пользователь прошел аутентификацию. Все остальное будет перенаправлено на страницу входа с кодом 302.

0 голосов
/ 07 апреля 2017

Существует другой краткий способ, использующий 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 более просто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...