如何在Django测试案例中设置cookie?
我在搞这个事情的时候遇到了一些困难,正常运行我的应用程序时会有会话功能,但我不知道怎么在我的测试案例中设置会话里的数据。
文档上说,在测试案例中,你必须先保存会话,才能在发起请求之前应用这些更改。 https://docs.djangoproject.com/en/1.2/topics/testing/#persistent-state
比如说:
from django.test import TestCase
class TestLogin(TestCase):
def test_processuser(self):
redirect = '/processuser/'
session = self.client.session
session["id"] = '1234'
session.save()
response = self.client.get(redirect)
但是从self.client.session得到的会话对象只是一个普通的Python字典吗?
深入看看代码,Client.session的调用是这样的:
def _session(self):
"""
Obtains the current session variables.
"""
if 'django.contrib.sessions' in settings.INSTALLED_APPS:
engine = import_module(settings.SESSION_ENGINE)
cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None)
if cookie:
return engine.SessionStore(cookie.value)
return {}
session = property(_session)
cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None)
返回的是 None
,所以它只是返回了一个字典,而不是会话存储。
看起来在保存会话之前,我需要在测试客户端做一些额外的准备?我在这方面经验不多,任何帮助都会很感激。
Django 1.2.5
Python 2.6.5
谢谢,
Asim。
4 个回答
与最受欢迎的回答相反,你可以直接在测试客户端上设置 cookies。
记住,所有东西都是对象,你只需要知道在哪里/什么需要修改
所以步骤是这样的:
client.cookies[key] = data
client.cookies
是来自标准库的 http.cookies.SimpleCookie
的一个实例,它的行为就像一个 dict
(字典)。所以你可以使用 .update
来批量更新 cookie 的值。如果你想修改其他 cookie 的值,比如 max-age
、path
、domain
等等,这个方法会很有用。
最后,如果你想设置一个 signed_cookie
,你可以像这样重用 Django 的助手函数:
from django.core.signing import get_cookie_signer
signed_cookie_value = get_cookie_signer(salt=key).sign(data)
client.cookies[key] = signed_cookie_value
注意盐值(salt)。它在两个地方(签名和获取)必须一致。如果签名时使用了不同的盐值,会生成一个不同的 cookie,当你调用 response.get_signed_cookie(key)
时就无法获取到。
编辑:这个答案现在已经过时了;从Django 1.7开始,你可以直接在测试客户端上设置cookie。
可以参考例如 这个问题的答案 或者 这个类似问题答案下的评论。
以下是旧的过时答案...
我加上这个是为了那些真的需要设置cookie的人,比如因为他们需要做一些Django认证机制没有覆盖的事情...
你不能直接在TestClient
对象上设置cookie,但如果你使用RequestFactory
类,你就可以做到。所以,不要这样做:
response = Client().post('/foo')
而是这样做:
request = RequestFactory().post('/foo')
request.COOKIES['blah'] = 'hello'
response = foo_view(request)
这里的foo_view
是对应'/foo'路径的视图,也就是你想要测试的视图。
希望这对某些人有帮助。