ambush
ambush

Reputation: 41

mocking method call in django template

I have created Product model's method in_stock(). I need to mock it both in view and in template render.

My test:

def test_my_view(self):
    with patch.object(models.Product, 'in_stock', return_value='sldkfsdf'):
    # OR with patch.object(views.Product, 'in_stock', return_value='sldkfsdf'):

        response = self.client.get(reverse('my_view'))
    print response.content

My view:

def my_view(request):
    product = Product.objects.get(pk=1)
    print product.in_stock()
    context = RequestContext(request, {
        'product': product,
    })

    return render_to_response('product/my_view.xml', context)

My template:

{{ product.in_stock }}

What I need in stdout:

sldkfsdf

and in template:

sldkfsdf

What I got in stdout:

sldkfsdf

in template:

<value, returned by original Product.in_stock() method>

So call of Product.in_stock() in my_view works well. It doesn't work only in template. :( What I'm doing wrong? What I need to mock method in template render?

And I have very old Django - 1.1.1 :(

Python 2.7

Mock 1.0.1

Upvotes: 4

Views: 1277

Answers (1)

jnns
jnns

Reputation: 5644

That has to do with the mock object being an instance of MagicMock instead of just Mock.

I guess this is due to Django accessing the methods/properties differently in the templates: {{ obj.foo }} could very well be both a method and an attribute on the object and that leads to magic methods like __getitem__() being used.

You can use patch(new=Mock, …) to have Mock instance created instead of MagicMock.

Upvotes: 1

Related Questions