【问题标题】:How to use session in TestCase in Django?如何在 Django 的 TestCase 中使用会话?
【发布时间】:2011-11-22 01:26:39
【问题描述】:

我想从测试中读取一些会话变量 (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)

【问题讨论】:

    标签: django session testing


    【解决方案1】:

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

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

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

    【讨论】:

    • 而之所以把session放到一个变量中,是因为每次写self.client.session,都会得到new object
    【解决方案2】:

    不幸的是,这并不像您目前希望的那样容易。正如您可能已经注意到的那样,如果您没有调用其他已为您设置了具有适当会话 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
    

    【讨论】:

    • 请注意:self.client.session 必须分配给一个变量。
    【解决方案3】:

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

    from django.contrib.sessions.middleware import SessionMiddleware
    from django.http import HttpRequest
    
    
    request = HttpRequest()
    
    middleware = SessionMiddleware()
    middleware.process_request(request)
    
    request.session.save()
    

    【讨论】:

    • 这很有帮助!
    • 对我来说,我得到“TypeError: __init__() 至少需要 3 个参数(给定 2 个)”所以我必须添加“settings.SESSION_ENGINE = 'django.contrib.sessions.backends.file'”让它发挥作用
    【解决方案4】:

    如果使用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/')
    

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

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 2015-11-08
        • 2013-02-07
        • 2021-02-08
        • 1970-01-01
        • 2011-04-11
        • 2020-03-06
        • 2014-08-09
        • 2020-08-01
        相关资源
        最近更新 更多