【问题标题】:Python - How to mock an instance inside a viewPython - 如何在视图中模拟实例
【发布时间】:2012-08-30 16:04:59
【问题描述】:

我正在测试我的视图,我需要在将上下文字典发送到 HttpResponse 对象之前对其进行一些断言,以确保我的视图按照我的预期进行计算。但是我怎么能断言事情呢?这是我在视图中尝试做的一个示例:

# some_app/views.py
def my_view(request):
    context = RequestContext(request)

    if request.GET.get('something'):
        value = # calculate the value somehow
        context.update(some_value=value)

    elif request.GET.get('something_else'):
        value = # calculate the value in other way
        context.update(some_value=value)
    # other stuff the view does

    return render_to_response('some_template.html', context_instance=context)

我突然想到,也许我可以修补视图以获得上下文实例:

# some_app/tests/unit/test_myview.py
from some_app import views
from mock import patch
from django.test.client import RequestFactory


class MyTest(TestCase):
    def test_my_view(self):
        request = RequestFactory().get('some_url', data={
            'param1': 'a',
            'param2': 'b'
        })
        with patch('some_app.views', [WHAT DO I INCLUDE HERE?]) as context:
            # by now, <context> should be the context instance created in the view
            response = views.my_view(request)
            self.assertTrue(context['some_value']['value1'])
            self.assertFalse(context['some_value']['value2'])
            self.assertRaises(IndexError, some_function,
                              context['some_value']['value1'])

但我想不出一个可行的想法:(

有没有什么方法可以在我的测试中让我在我的视图中创建的上下文实例可用?

感谢您的帮助:)

附注在这种情况下,浏览器内测试或检查生成的 html 不是一个选项:(

【问题讨论】:

    标签: python django unit-testing mocking


    【解决方案1】:

    如果您使用的是TemplateResponse,则可以通过response.context_data 测试上下文。试试:

    # some_app/views.py
    from django.template.response import TemplateResponse
    
    def my_view(request):
        context = {}
    
        if request.GET.get('something'):
            value = # calculate the value somehow
            context.update(some_value=value)
    
        elif request.GET.get('something_else'):
            value = # calculate the value in other way
            context.update(some_value=value)
        # other stuff the view does
    
        return TemplateResponse(request, 'some_template.html', context)
    

    测试:

    # some_app/tests/unit/test_myview.py
    from some_app import views
    from django.test.client import RequestFactory
    
    class MyTest(TestCase):
        def test_my_view(self):
            request = RequestFactory().get('some_url', data={
                'param1': 'a',
                'param2': 'b'
            })
    
            response = views.my_view(request)
            self.assertTrue(response.context_data['some_value']['value1'])
            self.assertFalse(response.context_data['some_value']['value2'])
            self.assertRaises(IndexError, some_function,
                                  response.context_data['some_value']['value1'])
    

    【讨论】:

    • AttributeError: 'HttpResponse' 对象没有属性 'context_data'
    • 你说得对。 context_dataTemplateResponse 中的属性,因此在您使用时可用,例如基于类的通用视图。
    猜你喜欢
    • 2020-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    • 2021-04-26
    • 2013-07-17
    相关资源
    最近更新 更多