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, он не тестирует форму входа, как следует из названия теста. Чтобы протестировать форму входа, вы можете либо мгновенно запустить форму входа и утверждать, что она ведет себя так, как ожидается, либо вас может устроить интеграционный тест, который публикует данные для входа и утверждает, что представление регистрирует пользователя, когда данные верны.