我想从测试中读取一些会话变量(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)
答案 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]
应该是您想要的!