简体   繁体   English

Django:在测试客户端上设置cookie?

[英]Django: set cookie on test client?

My Django site is set up with some middleware that on each request, checks for a cookie, and if it is not set, forwards the user elsewhere. 我的Django站点设置了一些中间件,在每个请求上检查cookie,如果没有设置,则将用户转发到其他地方。

I now want to run some tests on the site. 我现在想在网站上运行一些测试。 This is my code: 这是我的代码:

def test_contactform(self):
    response = self.client.get('/contact/')
    self.assertEqual(response.status_code, 200)
    print response
    self.assertTrue('Contact me' in response.content)

Unfortunately, this fails with: 不幸的是,这失败了:

Vary: Cookie
Content-Type: text/html; charset=utf-8
Location: http://testserver/ldap/?next=/contact/
Traceback (most recent call last):
  File "tests.py", line 43, in test_contactform
    self.assertEqual(response.status_code, 200)
AssertionError: 302 != 200

Can I either (i) set a cookie on the Django test client (and if so how) or (ii) require the Django test client to follow the redirect and test against the final page? 我可以(i)在Django测试客户端上设置cookie(如果是这样)或者(ii)要求Django测试客户端遵循重定向并测试最终页面?

None of the above worked for me (Django1.9, Python3.4). 以上都不适用于我(Django1.9,Python3.4)。 Found this solution here : 在此处找到此解决方案

from django.test import TestCase    
from http.cookies import SimpleCookie


class TestViewWithCookies(TestCase):

    def test_votes(self):
        self.client.cookies = SimpleCookie({'name': 'bla'})
        response = self.client.get('/vote/2')
        self.assertEqual(response.status_code, 200)

While the accepted answer is the right approach for this problem, I just want to point out that you can set cookies directly (ie approach number (i) as you call it), but not via the test client. 虽然接受的答案是解决此问题的正确方法,但我只想指出您可以直接设置cookie(即在您调用时接近编号(i)),但不能通过测试客户端。 Instead you need to use a RequestFactory to construct a request which you can set the cookie on, then pass that directly to the view in question. 相反,您需要使用RequestFactory来构造一个可以设置cookie的请求,然后将其直接传递给相关视图。

So instead of: 所以代替:

response = self.client.get('/contact/')

you do: 你做:

request = RequestFactory().get('/contact/')
request.COOKIES['thing'] = 'whatever'
response = contact_view(request)

where contact_view is the view serving /contact/ . 其中contact_view是视图服务/contact/

client.get方法采用follow参数,允许它遵循重定向:

response = self.client.get('/contact/', follow=True)

This is an old question but maybe this is handy for someone: 这是一个古老的问题,但也许这对某人来说很方便:

from http.cookies import SimpleCookie

from django.test import TestCase, Client


class CookieClientTests(TestCase):
    def test_cookie(self):
        cookies = SimpleCookie()
        cookies["cookie_key"] = "something"
        client = Client(HTTP_COOKIE=cookies.output(header='', sep='; '))

        resp = client.get("/")
        self.assertEqual(200, resp.status_code)

You can set cookies for test client by calling load on cookies attribute which is SimpleCookie object. 您可以通过调用load on cookies属性(即SimpleCookie对象)为测试客户端设置cookie。

from django.core import signing

self.client.cookies.load({
    'example': '123',
    'signed_example': signing.get_cookie_signer('signed_example').sign('123')
})

Django's test client is stateful - will persist cookies between tests and will ignore expire dates. Django的测试客户端是有状态的 - 将在测试之间保留cookie并忽略过期日期。 For removal, you need to manually remove cookie or create a new client. 要删除,您需要手动删除cookie或创建新客户端。 - See docs - 见文档

--- For Python 3 and Django 2+ ---对于Python 3和Django 2+

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

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