如何在Django测试案例中设置cookie?

1 投票
4 回答
5708 浏览
提问于 2025-04-16 18:35

我在搞这个事情的时候遇到了一些困难,正常运行我的应用程序时会有会话功能,但我不知道怎么在我的测试案例中设置会话里的数据。

文档上说,在测试案例中,你必须先保存会话,才能在发起请求之前应用这些更改。 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 个回答

2

与最受欢迎的回答相反,你可以直接在测试客户端上设置 cookies。

记住,所有东西都是对象,你只需要知道在哪里/什么需要修改

所以步骤是这样的:

client.cookies[key] = data

client.cookies 是来自标准库的 http.cookies.SimpleCookie 的一个实例,它的行为就像一个 dict(字典)。所以你可以使用 .update 来批量更新 cookie 的值。如果你想修改其他 cookie 的值,比如 max-agepathdomain 等等,这个方法会很有用。

最后,如果你想设置一个 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) 时就无法获取到。

8

编辑:这个答案现在已经过时了;从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'路径的视图,也就是你想要测试的视图。

希望这对某些人有帮助。

2

最简单的方法就是以某个用户的身份登录,这样测试客户端就会为你设置好cookie。

self.client.login(username,password)

这样就可以了。想了解更多,可以参考文档

撰写回答