Django 测试用例错误“WSGIRequest”对象没有属性“会话”

Posted

技术标签:

【中文标题】Django 测试用例错误“WSGIRequest”对象没有属性“会话”【英文标题】:Django Test Case Error 'WSGIRequest' object has no attribute 'session' 【发布时间】:2016-06-10 03:19:15 【问题描述】:

我正在尝试为我的 django 应用程序编写一些测试,但它抛出了一个错误:

File "/Users/croberts/.virtualenvs/litem/lib/python3.4/site-packages/django/contrib/auth/__init__.py", line 101, in login
    if SESSION_KEY in request.session:
AttributeError: 'WSGIRequest' object has no attribute 'session'

这是我要运行的代码:

class SimpleTest(TestCase):
    def setUp(self):
        self.request_factory = RequestFactory()

    def test_signup(self):
        request = self.request_factory.post("/signup/", 
            "email": "email@email.com", 
            "password": "password", 
            "password-confirm": "password", 
            "firm": "big law firm")
        response = signup_user(request)
        user = User.objects.get(email="email@email.com")
        self.assertEqual(user.username, "email@email.com")
        self.assertEqual(user.firm, "big law firm")
        self.assertEqual(response.status_code, 302) #if it's successful it redirects.

这是我的中间件:

MIDDLEWARE_CLASSES = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

和我安装的应用程序:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'patents',
]

【问题讨论】:

我刚刚更新了问题。在 setUp 方法中设置。 【参考方案1】:

尝试使用测试客户端而不是请求工厂。这还具有测试您的 URL 配置的优势。

class SimpleTest(TestCase):
    def test_signup(self):
        response = self.client.post("/signup/", 
            "email": "email@email.com", 
            "password": "password", 
            "password-confirm": "password", 
            "firm": "big law firm")
        user = User.objects.get(email="email@email.com")
        self.assertEqual(user.username, "email@email.com")
        self.assertEqual(user.firm, "big law firm")
        self.assertEqual(response.status_code, 302) #if it's successful it redirects.

【讨论】:

一个有用的花絮,如果您因为需要用户登录而遇到此问题,请尝试利用客户端的 login() 方法。就这么简单 my_client.login(username='my_username', password='my_password') "这还具有测试您的 URL 配置的优势。"如果我们正在编写 unit 测试,这是一个缺点【参考方案2】:

对于使用 Django 2.0 及更高版本的任何人 - RequestFactory() 无权访问中间件:

它不支持中间件。如果视图正常运行需要,会话和身份验证属性必须由测试本身提供。

https://docs.djangoproject.com/en/2.2/topics/testing/advanced/#the-request-factory

因此需要手动添加如下:

from django.contrib.sessions.middleware import SessionMiddleware

class SimpleTest(TestCase):
    def setUp(self):
        self.request_factory = RequestFactory()

        middleware = SessionMiddleware()
        middleware.process_request(self.request_factory)
        self.request_factory.session.save()

    def test_signup(self):
        ...

【讨论】:

有什么问题?【参考方案3】:

在 django 3.1 中,我得到了这个错误 'AttributeError: 'RequestFactory' object has no attribute 'COOKIES' 在遵循 @Alasdair 的回答之后。我通过先初始化请求解决了这个问题,下面是sn-p。

def setUp(self):
    request = RequestFactory().get('/')
    middleware = SessionMiddleware()
    middleware.process_request(request)
    request.session.save()

编辑 4.0 版的 sessionmiddlewre 需要一个位置参数:'get_response' 所以:

def setUp(self):
    request = RequestFactory().get('/')
    middleware = SessionMiddleware(request)
    middleware.process_request(request)
    request.session.save()
    

【讨论】:

以上是关于Django 测试用例错误“WSGIRequest”对象没有属性“会话”的主要内容,如果未能解决你的问题,请参考以下文章

Django 'WSGIRequest' 对象没有属性 'Post'

Django 1.8 admin 产生'WSGIRequest' object has no attribute 'user'的错误

Django admin 中抛出 'WSGIRequest' object has no attribute 'user'的错误

为啥获取“WSGIRequest”对象没有属性“数据”错误?

Django WSGIRequest对象

Django(25)WSGIRequest对象