[英]How to write a test case for this Django custom tag
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.