简体   繁体   中英

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.

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?

None of the above worked for me (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. 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.

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/ .

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.

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. For removal, you need to manually remove cookie or create a new client. - See docs

--- For Python 3 and Django 2+

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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