如何在Django中使用TestCase中的会话?

时间:2011-09-21 15:06:55

标签: django session testing

我想从测试中读取一些会话变量(Django TestCase)

如何以干净的方式做到这一点?

def test_add_docs(self):
    """
    Test add docs
    """
    # I would access to the session here:
    self.request.session['documents_to_share_ids'] = [1]

    response = self.client.get(reverse(self.document_add_view_id, args=[1]), follow=True)
    self.assertEquals(response.status_code, 200)

5 个答案:

答案 0 :(得分:16)

不幸的是,这并不像你希望的那样容易。您可能已经注意到,如果您没有调用已为您设置适当会话cookie的会话的其他视图,则直接使用self.client.session将无效。然后必须手动或通过其他视图设置会话存储/ cookie。

有一个打开的票证可以更轻松地模拟与测试客户端的会话:https://code.djangoproject.com/ticket/10899

除了故障单中的变通方法之外,如果您使用django.contrib.auth,还有一个技巧可以使用。测试客户端login()方法设置会话存储/ cookie,以便稍后在测试中使用。

如果您有任何其他设置会话的视图,请求它们也可以做到这一点(您可能有另一个视图设置会话,否则您的视图读取会话将非常不可用)。

from django.test import TestCase
from django.contrib.auth.models import User

class YourTest(TestCase):
    def test_add_docs(self):
        # If you already have another user, you might want to use it instead
        User.objects.create_superuser('admin', 'foo@foo.com', 'admin')

        # self.client.login sets up self.client.session to be usable
        self.client.login(username='admin', password='admin')

        session = self.client.session
        session['documents_to_share_ids'] = [1]
        session.save()

        response = self.client.get('/')  # request.session['documents_to_share_ids'] will be available

答案 1 :(得分:16)

从Django 1.7+开始,这更容易。确保将会话设置为变量,而不是直接引用它。

def test_something(self):
    session = self.client.session
    session['somekey'] = 'test'
    session.save()

andreaspelme的解决方法仅在旧版本的django中需要。见docs

答案 2 :(得分:2)

如果您需要在测试中初始化请求的会话以直接操作它:

from django.contrib.sessions.middleware import SessionMiddleware
from django.http import HttpRequest


request = HttpRequest()

middleware = SessionMiddleware()
middleware.process_request(request)

request.session.save()

答案 3 :(得分:0)

如果使用pytest测试我的django项目,则无法在视图中看到对会话的任何修改。 (这是因为未调用Sessions中间件。)

我发现以下方法很有用:

from unittest.mock import patch
from django.test import Client
from django.contrib.sessions.backends import db

def test_client_with_session():
    client = Client()
    session = {}  # the session object that will persist throughout the test
    with patch.object(db, "SessionStore", return_value=session):
        client.post('/url-that-sets-session-key/')

        assert session['some_key_set_by_the_view']

        client.get('/url-that-reads-session-key/')

这种方法的好处是不需要数据库访问。

答案 4 :(得分:-1)

您应该能够通过其Client属性访问session的会话变量,因此我猜self.client.session['documents_to_share_ids'] = [1]应该是您想要的!