简体   繁体   English

如何在 django 测试用例中设置 cookie?

[英]How to set a cookie in a django test case?

I'm struggling to figure this one out, sessions work when i run my application normally but i can't figure out how to set data in the session in my test case.我正在努力解决这个问题,当我正常运行我的应用程序时会话工作,但我无法弄清楚如何在我的测试用例中设置 session 中的数据。

The docs say in a test case you have to save the session to apply the changes before making the request.文档说在测试用例中,您必须保存 session 以在发出请求之前应用更改。 https://docs.djangoproject.com/en/1.2/topics/testing/#persistent-state https://docs.djangoproject.com/en/1.2/topics/testing/#persistent-state

eg例如

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)

However the session object returned from self.client.session is just a normal python dict?然而,从 self.client.session 返回的 session object 只是一个普通的 Z23EEEB4347BDD26BZDDdict6B7EE?9

Diging into the code the Client.session call is this:深入研究 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) returns None so it just returns a dict in stead of a session store. cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None)返回None所以它只返回一个字典而不是 session 存储。

It looks like i have to do some more preparation in the test client before i save a session?在我保存 session 之前,看起来我必须在测试客户端中做更多的准备工作? Not really got much experience in this any help would be appreciated.在这方面并没有太多经验,任何帮助将不胜感激。

Django 1.2.5 Python 2.6.5 Django 1.2.5 Python 2.6.5

Cheers,干杯,

Asim.阿西姆。

Edit: this answer is now outdated;编辑:这个答案现在已经过时了; as of at least Django 1.7, you can just set the cookie directly on the test client.至少从 Django 1.7 开始,您可以直接在测试客户端上设置 cookie。

See eg this answer to this question or the comments on this answer to another, similar, question .例如,请参阅this answer to this question对此答案对另一个类似问题的评论

Old outdated answer follows...旧的过时答案如下...


Adding this for people who really do need to set a cookie, eg because they need to do something which isn't covered by the Django auth mechanism...确实需要设置 cookie 的人添加此功能,例如因为他们需要做 Django 身份验证机制未涵盖的事情...

You can't set cookies directly on TestClient objects but if you use the RequestFactory class you can do it.你不能直接在TestClient对象上设置 cookies 但是如果你使用RequestFactory class 你可以做到。 So instead of (say):所以而不是(说):

response = Client().post('/foo')

you do:你做:

request = RequestFactory().post('/foo')
request.COOKIES['blah'] = 'hello'
response = foo_view(request)

where foo_view is the view corresponding to the '/foo' path, ie the view you're looking to test.其中foo_view是对应于 '/foo' 路径的视图,即您要测试的视图。

HTH somebody.有人。

The simplest thing would be to login as someone, so the test client would set the cookie for you.最简单的事情是以某人身份登录,因此测试客户端会为您设置 cookie。

self.client.login(username,password)

should do.应该做。 Refer the documentation for more.有关更多信息,请参阅文档

For other people who are running into this problem please be aware that the Client.logout() function will throw away your cookies.对于遇到此问题的其他人,请注意Client.logout() function 将丢弃您的 cookies。 For example:例如:

response = self.client.post(self.url, self.data)
print response.client.cookies.items()  # Displays the cookie you just set

self.client.logout()

response = self.client.post(reverse('loginpage'), {'username': 'username', 'password': 'password'}, follow=True)
print response.client.cookies.items()  # Does not display the cookie you set before since it got destroyed by logout()

To make sure your cookies stay alive during testing make a call to your logout page in stead of using the Client.logout() function, like so:为了确保您的 cookies 在测试期间保持活动状态,请调用您的注销页面而不是使用Client.logout() function,如下所示:

response = self.client.post(self.url, self.data)
print response.client.cookies.items()  # Displays the cookie you just set

self.client.get(reverse('logoutpage'))

response = self.client.post(reverse('loginpage'), {'username': 'username', 'password': 'password'}, follow=True)
print response.client.cookies.items()  # Does display the cookie you set before since it did not get destroyed by client.logout()

Contrary to the most upvoted answer, you CAN set cookies directly on the test client.与最受好评的答案相反,您可以直接在测试客户端上设置cookies

Remember everything is an object, you just have to know where/what to patch记住一切都是 object,你只需要知道在哪里/什么补丁

so it goes like this:所以它是这样的:

client.cookies[key] = data

client.cookies is an instance of http.cookies.SimpleCookie from the standard library and it behaves like a dict . client.cookies是标准库中http.cookies.SimpleCookie的一个实例,它的行为类似于dict so you can use .update for bulk updates to a cookies value.因此您可以使用.update批量更新 cookies 值。 This can be useful if you want to alter other cookie values like max-age , path domain etc.如果您想更改其他 cookie 值(如max-agepath domain等),这将很有用。

Finally, if you want to set a signed_cookie , You can reuse the helpers from django like this:最后,如果你想设置一个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

Pay attention to the salt.注意盐。 It has to match on both ends (Signing and retrieval).它必须在两端匹配(签名和检索)。 A Different salt value for signing would generate a different cookie that cannot be retrieved when you call response.get_signed_cookie(key)用于签名的不同盐值会生成不同的 cookie,当您调用response.get_signed_cookie(key)时无法检索该 cookie

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM