Сам Джанго.клиент.login (...) не работает в модульных тестах


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

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

    { 
        "pk": 1, 
        "model": "auth.user", 
        "fields": { 
            "username": "homer", 
            "is_active": 1, 
            "password": 
"sha1cd335449e2cd7efb8b3723fb9958fe3bb100a30f2", 
            ... 
        } 
    }

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

2) использовать в функции настройки (хотя я бы предпочел сохранить все в моем классе светильников):
def setUp(self): 
       User.objects.create_user('homer', 'ho...@simpson.net', 'simpson') 

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

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

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

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

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

спасибо.

5 54

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 метод, стоимостью , 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')

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

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

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

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

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)

этот тест работал для меня.

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

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