简体   繁体   中英

How to test a Django custom filter?

This question is similar to Testing a custom Django template filter , but unlike in that example, the filter is actually defined in a module in the templatetags directory as described in https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/#writing-custom-template-filters . Here is the filter code in templatetags/label_with_classes.py :

from django import template

register = template.Library()


@register.filter(is_safe=True)
def label_with_classes(bound_field):
    classes = f"{'active' if bound_field.value() else ''} {'invalid' if bound_field.errors else ''}"
    return bound_field.label_tag(attrs={'class': classes})

Here is my first stab at a test for it:

from ..templatetags.label_with_classes import label_with_classes
from django.test import SimpleTestCase
from django.template import Context, Template


from ..forms.sessions import SessionForm


class CustomFilterTest(SimpleTestCase):
    def test_1(self):
        form = SessionForm(data={})
        self.assertFalse(form.is_valid())
        self.assertEqual(
            form.errors,
            {'session_number': ['This field is required.'],
             'family': ['This field is required.'],
             'session_type': ['This field is required.']})


        template = Template('{{ form.session_number|label_with_classes }}')
        context = Context({'form': form})

        output = template.render(context)

The problem is that I get an error that the filter was not found:

django.template.exceptions.TemplateSyntaxError: Invalid filter: 'label_with_classes'

This is because the test case doesn't mimic the behavior of registering the filter and loading it in the template. It seems like in the Django source code, for example https://github.com/django/django/blob/master/tests/template_tests/filter_tests/test_join.py , there is an elaborate setup decorator which provides the test class with a self.engine whose render_to_string method has the required filters already installed.

Do I basically have to copy the Django source code to write an integration-style test for my custom filter? Or is there a simpler way (besides just testing it as a function)?

I suspect you need to load your template module:

...
template = Template("""{% load label_with_classes %}
{{ form.session_number|label_with_classes }}""")
...

See the relevant documentation .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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