it-swarm.com.ru

Self.client.login (...) Django не работает в модульных тестах

Я создал пользователей для своих модульных тестов двумя способами:

1) Создайте приспособление для "auth.user", которое выглядит примерно так:

    { 
        "pk": 1, 
        "model": "auth.user", 
        "fields": { 
            "username": "homer", 
            "is_active": 1, 
            "password": 
"sha1$72cd3$4935449e2cd7efb8b3723fb9958fe3bb100a30f2", 
            ... 
        } 
    }

Я пропустил, казалось бы, неважные части.

2) Используйте 'create_user' в функции setUp (хотя я бы предпочел оставить все в своем классе фикстур):

def setUp(self): 
       User.objects.create_user('homer', '[email protected]', 'simpson') 

Обратите внимание, что в обоих случаях пароль симпсон.

Я проверял, что эта информация снова и снова корректно загружается в тестовую базу данных. Я могу получить объект User с помощью User.objects.get. Я могу проверить правильность пароля, используя 'check_password.' Пользователь активен.

Тем не менее, неизменно, self.client.login (username = 'homer', password = 'simpson') терпит неудачу. Я сбит с толку относительно того, почему. Я думаю, что прочитал каждую дискуссию в Интернете, касающуюся этого. Кто-нибудь может помочь?

Код входа в мой модульный тест выглядит так:

    login = self.client.login(username='homer', password='simpson') 
    self.assertTrue(login) 

Благодарю.

65
thebossman

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

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')
88
Pedro M Duarte

Более простой способ - использовать 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])
33
WeizhongTu

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

https://docs.djangoproject.com/es/1.9/topics/http/sessions/#enabling-sessions

5
e-satis

Можете ли вы проверить, как показано ниже,

from Django.test import TransactionTestCase, Client

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

    def test_history(self):
        self.client.login(username=self.user.username, password='[email protected]')
        # 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