【问题标题】:How do I modify the session in the Django test framework如何在 Django 测试框架中修改会话
【发布时间】:2011-05-26 02:56:44
【问题描述】:

我的网站允许个人在没有登录的情况下通过基于当前 session_key 创建用户来贡献内容

我想为我的视图设置一个测试,但似乎无法修改 request.session:

我想这样做:

from django.contrib.sessions.models import Session
s = Session()
s.expire_date = '2010-12-05'
s.session_key = 'my_session_key'
s.save()
self.client.session = s
response = self.client.get('/myview/')

但我得到了错误:

AttributeError: can't set attribute

关于如何在发出 get 请求之前修改客户端会话的想法? 我见过this,但它似乎不起作用

【问题讨论】:

  • session 是一个类似dict 的对象,你应该使用s[x] 来获取和设置值

标签: python django django-testing django-sessions


【解决方案1】:

django 测试框架的客户端对象使得接触会话成为可能。详情看http://docs.djangoproject.com/en/dev/topics/testing/?from=olddocs#django.test.client.Client.session

小心:To modify the session and then save it, it must be stored in a variable first (because a new SessionStore is created every time this property is accessed)

我认为下面这样的东西应该可以工作

s = self.client.session
s.update({
    "expire_date": '2010-12-05',
    "session_key": 'my_session_key',
})
s.save()
response = self.client.get('/myview/')

【讨论】:

  • 嗨,Luc,感谢您的帮助,但这不起作用。我收到以下错误: AttributeError: 'dict' object has no attribute 'save' 这是因为 client.session 对象是字典。似乎 client.session 仅在发出请求后才成为真正的 Session 对象(并且仅当用户登录时)。还有其他建议吗?您可以通过输入(从 shell)重复此操作: from django.test import Client client = Client() s = client.session s['expire_date']='2010-12-05' s['session_key']=' my_session_key's.save()
  • 看起来 luc 建议的应该可以工作,但它是一个 django 错误:code.djangoproject.com/ticket/11475
  • 为 Andrew 加 1 - 这个 bug 似乎至少有 4 年的历史了。
  • 关于前2个cmets,我相信这个bug已经在followingcommit修复了。
  • 这对我有用。看起来其他人在上面评论的错误已修复。
【解决方案2】:

我就是这样做的(灵感来自http://blog.mediaonfire.com/?p=36 中的解决方案)。

from django.test import TestCase
from django.conf import settings
from django.utils.importlib import import_module

class SessionTestCase(TestCase):
    def setUp(self):
        # http://code.djangoproject.com/ticket/10899
        settings.SESSION_ENGINE = 'django.contrib.sessions.backends.file'
        engine = import_module(settings.SESSION_ENGINE)
        store = engine.SessionStore()
        store.save()
        self.session = store
        self.client.cookies[settings.SESSION_COOKIE_NAME] = store.session_key

之后,您可以将测试创建为:

class BlahTestCase(SessionTestCase):

    def test_blah_with_session(self):
        session = self.session
        session['operator'] = 'Jimmy'
        session.save()

等等……

【讨论】:

  • 在 django 1.6 中使用 Pickle 序列化程序(而不是现在用于 SESSION_SERIALIZER 的标准 JSONSerializer)是否仍然有效
【解决方案3】:

正如 Andrew Austin 已经提到的,由于这个错误,它不起作用:https://code.djangoproject.com/ticket/11475

你可以这样做:

from django.test import TestCase
from django.test.client import Client
from django.contrib.auth.models import User

class SessionTestCase(TestCase):
    def setUp(self):
        self.client = Client()
        User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
        self.client.login(username='john', password='johnpassword')

    def test_something_with_sessions(self):
        session = self.client.session
        session['key'] = 'value'
        session.save()

使用 User.objects.create_user() 和 self.client.login() 创建并登录用户后,如上面的代码所示,会话应该可以工作。

【讨论】:

    【解决方案4】:

    您可以创建一个自定义视图来插入虚拟数据,例如会话。

    对应url的视图:/dummy/:

    def dummy(request):
        # dummy init data
        request.session['expiry_date'] = '2010-12-05'
        return HttpResponse('Dummy data has been set successfully')
    

    比在测试脚本中只需调用self.client.get('/dummy/')

    在手动测试时,我也使用这个虚拟视图来初始化会话中的虚拟数据。

    【讨论】:

      【解决方案5】:

      根据文档,您可以通过例如向测试客户端中的会话添加值

      def test_something(self):
          session = self.client.session
          session['somekey'] = 'test'
          session.save()
      

      https://docs.djangoproject.com/en/dev/topics/testing/tools/#django.test.Client.session

      这将让您测试需要会话中的数据才能正常工作的视图。

      所以对于这个问题:

      session = self.client.session
         session['expire_date'] = '2010-12-05'
         .....
         session.save()
      

      【讨论】:

        猜你喜欢
        • 2021-08-18
        • 2011-01-11
        • 2015-10-24
        • 2016-02-24
        • 1970-01-01
        • 1970-01-01
        • 2013-08-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多