[英]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-age
、 path
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.