Django - Тестирование представления входа - AttributeError: объект 'HttpRequest' не имеет атрибута 'user'

Я пытаюсь протестировать Django Login View с помощью TestCase, но получаю следующую ошибку -

ERROR: test_login_form (accounts.tests.LoginPageTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/farhan/Documents/_playground_new/django_playground/cbv-dfb/accounts/tests.py", line 53, in test_login_form
    logged_in = self.client.force_login(new_user)
  File "/home/farhan/Documents/_playground_new/django_playground/cbv-dfb/venv/lib/python3.8/site-packages/django/test/client.py", line 619, in force_login
    self._login(user, backend)
  File "/home/farhan/Documents/_playground_new/django_playground/cbv-dfb/venv/lib/python3.8/site-packages/django/test/client.py", line 631, in _login
    login(request, user, backend)
  File "/home/farhan/Documents/_playground_new/django_playground/cbv-dfb/venv/lib/python3.8/site-packages/django/contrib/auth/__init__.py", line 135, in login
    user_logged_in.send(sender=user.__class__, request=request, user=user)
  File "/home/farhan/Documents/_playground_new/django_playground/cbv-dfb/venv/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 180, in send
    return [
  File "/home/farhan/Documents/_playground_new/django_playground/cbv-dfb/venv/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 181, in <listcomp>
    (receiver, receiver(signal=self, sender=sender, **named))
  File "/home/farhan/Documents/_playground_new/django_playground/cbv-dfb/accounts/views.py", line 29, in on_user_logged_out
    f"{request.user.username} successfully logged in!",
AttributeError: 'HttpRequest' object has no attribute 'user'

У меня есть сигнал user_logged_in, который добавляет сообщение от фреймворка Django messages при входе в систему. Вот код -


@receiver(user_logged_in)
def on_user_logged_in(sender, request, **kwargs):
    messages.add_message(
        request,
        messages.INFO,
        f"{request.user.username} successfully logged in!",
    )

А вот код для модульного теста -

class LoginPageTests(TestCase):
    username = "newuser"
    email = "newuser@email.com"
    password = "averydeifficultpasswordtobreak"

    def test_login_page_status_code(self):
        response = self.client.get("/accounts/login/")
        self.assertEqual(response.status_code, 200)

    def test_view_url_by_name(self):
        response = self.client.get(reverse("login"))
        self.assertEqual(response.status_code, 200)

    def test_view_uses_correct_template(self):
        response = self.client.get(reverse("login"))
        self.assertTemplateUsed(response, "registration/login.html")

    def test_login_form(self):
        new_user = get_user_model().objects.create_user(self.username, self.email)
        new_user.set_password(self.password)
        new_user.save()

        logged_in = self.client.login(username=self.username, password=self.password)
        self.assertEqual(logged_in, True)

Если я просто закомментирую код сигнала, тест проходит нормально. Как я могу решить эту проблему?

Сигнал посылает пользователя в качестве аргумента, поэтому используйте его вместо request.user.

@receiver(user_logged_in)
def on_user_logged_in(sender, request, user, **kwargs):
    messages.add_message(
        request,
        messages.INFO,
        f"{user.username} successfully logged in!",
    )

Обратите внимание, что self.client.login() использует тестовый клиент Django, он не тестирует форму входа, как следует из названия теста. Чтобы протестировать форму входа, вы можете либо мгновенно запустить форму входа и утверждать, что она ведет себя так, как ожидается, либо вас может устроить интеграционный тест, который публикует данные для входа и утверждает, что представление регистрирует пользователя, когда данные верны.

Вернуться на верх