Django - 测试登录视图 - AttributeError:'HttpRequest'对象没有属性'user'

Posted

技术标签:

【中文标题】Django - 测试登录视图 - AttributeError:\'HttpRequest\'对象没有属性\'user\'【英文标题】:Django - Testing Login View - AttributeError: 'HttpRequest' object has no attribute 'user'Django - 测试登录视图 - AttributeError:'HttpRequest'对象没有属性'user' 【发布时间】:2021-11-02 12:16:28 【问题描述】:

我正在尝试使用 TestCase 测试 Django 登录视图,但出现以下错误 -

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 消息框架添加一条消息。这是代码 -


@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)

如果我只是简单地注释掉信号代码,测试运行良好。我该如何解决这个问题?

【问题讨论】:

也请发表您的看法。 @Ram,这是我可以使用来自 django.contrib.auth.urls 的 reverse("login") 访问的默认 Django 登录视图 【参考方案1】:

我正在进行测试并遇到了类似的问题。您不断获得MessageFailure error,因为您仍在使用signal 中的HttpRequest。罪魁祸首是处理后端的Client(),但message 参数(HttpRequest)有问题。

您可以查看我的topic,我在其中描述了这些经历。

【讨论】:

【参考方案2】:

信号将用户作为参数发送,因此请使用它而不是 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 测试客户端,它并没有像测试名称所暗示的那样测试登录表单。要测试您的登录表单,您可以实例化登录表单并断言其行为符合预期,或者您可能会对发布登录详细信息并断言当详细信息正确时视图登录用户的集成测试感到满意。

【讨论】:

谢谢。我现在收到此错误 - MessageFailure( django.contrib.messages.api.MessageFailure: You cannot add messages without installing django.contrib.messages.middleware.MessageMiddleware 如果您搜索该错误消息,this page 有一些建议。 谢谢!我会调查的。我刚刚开始使用 Django 进行单元测试,所以在这个阶段我有点困惑。感谢您的帮助!

以上是关于Django - 测试登录视图 - AttributeError:'HttpRequest'对象没有属性'user'的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 单元测试中使用会话对象

使用通用登录视图时出现“名称'django'未定义”错误?

如何不使用 Django 的管理员登录视图?

在视图中添加占位符。在 Django 中登录

Django 自定义登录视图 -> 会话不持久

有啥方法可以更改登录的 Django-rest-auth 视图?