简体   繁体   English

如何为此Django自定义标签编写测试用例

[英]How to write a test case for this Django custom tag

  • Django version : v1.10 Django版本:v1.10
  • Python : 3.5 (this is important as it turns out .. look at the answer) Python:3.5(这很重要,因为事实证明..查看答案)

I found this answer in order to have a if-else tag to compare the request.path in Django templates 我找到了这个答案,以便有一个if-else标签来比较Django模板中的request.path

https://stackoverflow.com/a/19895344/80353 https://stackoverflow.com/a/19895344/80353

from django import template
from django.template.base import Node, NodeList, TemplateSyntaxError

register = template.Library()

class IfCurrentViewNode(Node):
    child_nodelists = ('nodelist_true', 'nodelist_false')

    def __init__(self, view_name, nodelist_true, nodelist_false):
        self.view_name = view_name
        self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false

    def __repr__(self):
        return "<IfCurrentViewNode>"

    def render(self, context):
        view_name = self.view_name.resolve(context, True)
        request = context['request']
        if request.resolver_match.url_name == view_name:
            return self.nodelist_true.render(context)
        return self.nodelist_false.render(context)


def do_ifcurrentview(parser, token):
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError("'%s' takes at least one argument"
                                  " (path to a view)" % bits[0])
    view_name = parser.compile_filter(bits[1])
    nodelist_true = parser.parse(('else', 'endifcurrentview'))
    token = parser.next_token()
    if token.contents == 'else':
        nodelist_false = parser.parse(('endifcurrentview',))
        parser.delete_first_token()
    else:
        nodelist_false = NodeList()
    return IfCurrentViewNode(view_name, nodelist_true, nodelist_false)

@register.tag
def ifcurrentview(parser, token):
    """
    Outputs the contents of the block if the current view match the argument.

    Examples::

        {% ifcurrentview 'path.to.some_view' %}
            ...
        {% endifcurrentview %}

        {% ifcurrentview 'path.to.some_view' %}
            ...
        {% else %}
            ...
        {% endifcurrentview %}
    """
    return do_ifcurrentview(parser, token)

Was wondering if there's a way to write test case to cover this custom code? 想知道是否存在编写测试用例以覆盖此自定义代码的方法吗?

I want to maintain our test coverage percentage 我想维持我们的考试覆盖率

You should be able to cover most, if not all of that using mock. 您应该能够使用模拟功能涵盖大部分(如果不是全部)内容。 For example, let's say you want to test the render function: 例如,假设您要测试render函数:

from unittest.mock import Mock

def test_render_url_match(self):
    mock_request = Mock()
    matching_url_name = 'url_name'
    mock_nodelist_true, mock_nodelist_false = Mock(), Mock()
    mock_view_name = Mock()
    mock_view_name.resolve.return_value = matching_url_name
    mock_request.resolver_match.url_name = matching_url_name
    mock_context = {'request': mock_request}

    custom_node = IfCurrentViewNode(mock_view_name, mock_nodelist_true, mock_nodelist_false)
    custom_node.render(mock_context)

    # You can then test that the correct function was called:
    # you can change to `assert_called_once` if using Python 3.6
    mock_nodelist_true.render.assert_called_once_with(mock_context)

By setting up the mocks that way, I've ensured that this request.resolver_match.url_name == view_name will be true, and hit this line: return self.nodelist_true.render(context) . 通过以这种方式设置return self.nodelist_true.render(context) ,我确保此request.resolver_match.url_name == view_name将为true,并单击以下行: return self.nodelist_true.render(context) You can then set up the url name so they don't match and cover the false case. 然后,您可以设置网址名称,以使它们不匹配并覆盖错误的情况。

Then, for the do_ifcurrentview function, you can mock out whatever pieces you need to as well. 然后,对于do_ifcurrentview函数,您还可以模拟出所需的任何部分。 Maybe you don't want to mess with getting parser.compile_filter to return what you need. 也许您不想让parser.compile_filter返回您需要的东西。 Just mock it and change the return value: 只是模拟它并更改返回值:

with mock.patch('parser.compile_filter') as mock_compile_filter:
    mock_compile_filter.return_value = 'my_expected_view_name'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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