# Using mocking to test that a Django view renders as expected

I have a Django view that ends with this...

return render(request, 'define/see_all.html', context)


I have mocked the render function and

@patch('define.views_func.render')
def test_get_define_see_all_complete(self, mock_render):
"""Testing that the queryset returned properly"""
things = AllThings(group="Word Editors")
things.model['definition'].is_complete = True
things.model['definition'].save()
t_url = reverse(
'define:get',
kwargs={'language': things.model['language']}) \
+ "?action=seeall&complete=True"
see_all(req, {'language': things.model['language']})
self.assertTrue(len(mock_render.call_args[0][2]['words'].object_list) == 1)


I am basically just trying to see that the context that was passed to render contains the appropriate output from the view, but yuck the last line looks like garbage to me and I know I will not understand it if I come back to look at it later. Is there a better way to do this?

• Do you really need to patch the render function? If you are using test client from django you can access the context that was sent, check documentation page here – Gabriel Muj Nov 11 '16 at 7:56

How about doing things in two steps?

render_context = mock_render.call_args[0][2]
self.assertTrue(len(render_context["words"].object_list) == 1


This way it should be reasonably easy to figure out what call_args[0][2] are.

Although, I'm not sure if it's a good idea to test things this way. There still could be a bug if the template's broken, and you're essentially testing the internal API (the context data structure) in the middle of the function. Unless that is what you want to test, of course.

Maybe it would be a better idea to factor the querying logic to its own function. I guess, one possible way of doing this would be probably a class-based view, like some ListView derivative.

This way you could test its get_queryset() (not the get_context_data) to return the dataset you expect.

And you can also use test Client to return a sanely-looking rendered template - parse it with something like lxml or BeautifulSoup, or just check response string with "Word Editors" in response (although it may make sense to use more "unique" strings, like UUIDs in this case).