Django / Python unittest side_effect usage

The second in what might become a series in "unittesting strange code". I have the following function I am testing:

def filter_queryset(self):
    """
        Filter our base queryset
    """
    # Get our base queryset
    queryset = self.get_queryset()
    if self.tags:
        try:
            # Try the django-taggit way of filtering by tags
            queryset = queryset.filter(tags__name__in=self.tags)
        except FieldError:
            # Our queryset object is using django-taggable instead
            # filter by tags the ugly way...
            for tag in self.tags:
                queryset = queryset.filter(tags__icontains=tag)
    return queryset

First off let me assure you I realise that this is... ugly. It's a sad requirement for now that we are using two different django tag libraries, django-taggit and django-taggable. (Never use django-taggable). And this is about as generic a way as I can think of to have a filter function that works with both with the minimum amount of fuss. The issue that occurs when testing is that in order to test the functionality, I need to get queryset.filter() to raise a FieldError(). Fine, easily done with setting it up as a mock object with a side effect:

  def side_effect(*args, **kwargs):
        if kwargs.get("tags__name__in", None):
            return FieldError()

    mock_queryset = MagicMock()
    mock_queryset.filter.side_effect = side_effect

The issue with this is that because of the FieldError being raised, filter() can no longer be used in the except part of the function, meaning I cannot test for the correct called_count, or assert_any_call() etc.

Other than an upheaval of the codebase to only use one version of tagging, what are the ways around this?

Answers


Just make a separate function that raises FieldError if it's called one way, and doesn't in the other:

expected_return = MagicMock()

def fake_filter(**kwargs):
    if 'tags__name__in' in kwargs:
        raise FieldError()
    if 'tags__icontains' in kwargs:
        return expected_return
    raise ValueError("Neither expected kwarg present")

mock_queryset = MagicMock()
mock_queryset.filter = fake_filter

et cetera. I see now that you already do that with your side effect function, you can just do the same but more.


Need Your Help

get radiobutton value in jqgrid

jqgrid jqgrid-asp.net jqgrid-php jqgrid-formatter jqgrid-inlinenav

i'm starter in jqGrid, i want implement inline editing and write this code:

Passing a parameter to jquery using ajax mvc3 .net

c# jquery ajax asp.net-mvc-3

I am building a backoffice to a certain site, and here i need to delete the comments from the database using ajax, the problem is i cant pass the id i want to hide after deleting to jquery in ajax.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.