Django login_required unittesting [дубликат]

Примером этого исключаемого исключения является: Когда вы пытаетесь проверить что-то, это null.

Например:

string testString = null; //Because it doesn't have a value (i.e. it's null; "Length" cannot do what it needs to do)

if (testString.Length == 0) // Throws a nullreferenceexception
{
    //Do something
} 

Время выполнения .NET исключение NullReferenceException при попытке выполнить действие над чем-то, что не было инстанцировано, т.е. код выше.

По сравнению с ArgumentNullException, которое обычно выбрано как защитная мера, если метод ожидает, что то, что происходит

Дополнительная информация находится в C # NullReferenceException и Null Parameter .

53
задан thebossman 12 April 2010 в 00:17
поделиться

5 ответов

Код, который не работает:

from django.contrib.auth.models import User
from django.test import Client

user = User.objects.create(username='testuser', password='12345')

c = Client()
logged_in = c.login(username='testuser', password='12345')

Почему это не работает?

В приведенном выше фрагменте, когда создан User, фактический пароль хэш установлен в 12345. Когда клиент вызывает метод login, значение аргумента password, 12345 передается через хэш-функцию, что приводит к чему-то вроде

hash('12345') = 'adkfh5lkad438....'

. Затем это сравнивается с хэш, хранящийся в базе данных, и клиенту отказано в доступе, потому что 'adkfh5lkad438....' != '12345'

Решение

Правильная вещь - вызвать функцию set_password, которая передает данную строку через хеш-функцию и сохраняет результат в User.password.

Кроме того, после вызова set_password мы должны сохранить обновленный объект User в базе данных:

user = User.objects.create(username='testuser')
user.set_password('12345')
user.save()

c = Client()
logged_in = c.login(username='testuser', password='12345')
69
ответ дан Pedro M Duarte 28 August 2018 в 02:40
поделиться
  • 1
    Вы используете User.objects.create_superuser() и User.objects.create_user(), которые выполняют именно этот вызов set_password(). – vdboor 12 April 2016 в 17:17
  • 2
    как насчет того, когда вы регистрируете человека в – rocky raccoon 14 March 2017 в 23:30
  • 3
    добавить к комментарию @vdboor: обратите внимание, что поскольку Django 1.4 также User.objects.get_or_create() выполняет требуемый вызов set_password() – furins 28 March 2018 в 10:17

Более простой способ - использовать force_login , новый в Django 1.9.

force_login(user, backend=None)

Например:

class LoginView(TestCase):
    def setUp(self):
        self.client.force_login(User.objects.get_or_create(username='testuser')[0])
21
ответ дан approxiblue 28 August 2018 в 02:40
поделиться

Если кто-то все еще следит за этим, я думаю, что атрибуты 'is_staff' и 'is_active' должны быть сохранены True для успешного входа в систему ......

self.user = User.objects.create(username='testuser',password='pwd',is_active=1,is_staff=1)

-3
ответ дан Arindam Roychowdhury 28 August 2018 в 02:40
поделиться
  • 1
    Это просто сработало ........... self.user = User.objects.create (username = 'testuser', password = '12345', is_active = True, is_staff = True, is_superuser = True) self. user.set_password ('hello') self.user.save () user = authenticate (username = 'testuser', password = 'hello') login = self.c.login (имя пользователя = 'testuser', password = 'hello' ) self.assertTrue (логин) – Arindam Roychowdhury 14 November 2012 в 14:08
  • 2
    Это не имеет никакого отношения к is_staff, который определяет, что доступ к административной панели вообще предоставляется. Как вы можете видеть, данные в начальной публикации уже имеют is_active = 1, и это также значение по умолчанию для User.objects.create(). – jnns 14 November 2013 в 11:46
  • 3
    @arindamroychowdhury - Вау, это на самом деле сработало .. (Ваш комментарий, то есть) – Richard de Wit 19 June 2014 в 08:20
  • 4
    Это может быть проблема с версией, но мне пришлось прокомментировать ваш запрос подлинности. Кроме этого, ваш комментарий работал как чемпион! При дальнейшем тестировании я обнаружил, что is_active, is_superuser, и is_staff не нужны. Дело в том, что это был вызов set_password. – dolphus333 29 April 2016 в 13:51

Убедитесь, что django.contrib.sessions добавлен в INSTALLED_APPS, потому что client.login() проверяет, что он есть, и всегда будет возвращать false, если это не так:

https: //docs.djangoproject. ком / эс / 1.9 / темы / HTTP / сессии / # стимулирующей сессии

5
ответ дан Chris Adams 28 August 2018 в 02:40
поделиться
  • 1
    +1 для этого. Даже с django.contrib.sessions.middleware.SessionMiddleware в классах промежуточного программного обеспечения вы все равно не можете войти через django.test.Client. Мне понадобится неделя, чтобы найти этот ответ – pupil 7 April 2016 в 05:29

Вы можете проверить, как показано ниже,

from django.test import TransactionTestCase, Client

class UserHistoryTest(TransactionTestCase):
    self.user = User.objects.create(username='admin', password='pass@123', email='admin@admin.com')
    self.client = Client() # May be you have missed this line

    def test_history(self):
        self.client.login(username=self.user.username, password='pass@123')
        # get_history function having login_required decorator
        response = self.client.post(reverse('get_history'), {'user_id': self.user.id})
        self.assertEqual(response.status_code, 200)

Этот тестовый пример работал для меня.

3
ответ дан Muthuvel 28 August 2018 в 02:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: