Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django rest framework unit test viewsets mixins

I need to unit test a Django REST framework mixin. so i go for a test that looks like this:

class TestMyMixin(APITestCase):

    class DummyView(MyMixin,
        viewsets.ModelViewSet):
        queryset = MyModel.objects.all()
        serializer_class = MyModelSerializer

        #some properties omitted

    def setUp(self):
        self.view = self.DummyView.as_view(\
            actions={'get':'list'})

    def test_basic_query(self):
        instance = MyModel.objects.create(\
            **{'name':'alex'})
        request = APIRequestFactory().get(\
            '/fake-path?query=ale',
            content_type='application/json')
        response = self.view(request)
        self.assertEqual(\
            response.status_code,status.HTTP_200_OK)
        json_dict = json.loads(\
            response.content.decode('utf-8'))
        self.assertEqual(json_dict['name'],instance.name)

However when i run this test i do get the:

raise ContentNotRenderedError('The response content must be 'django.template.response.ContentNotRenderedError: The response content must be rendered before it can be accessed.

It seems that django REST framework would have some different approach to unit test viewsets, mixins and views.
But I can not figure out what should I do instead.
The official docs page suggests to use real urls, but it suits more for acceptance tests rather than for unit tests.

like image 568
canufeel Avatar asked Feb 17 '16 11:02

canufeel


1 Answers

This problem occurs because your view's response doesn't get rendered, thus the _is_rendered is False and the ContentNotRenderedError exception gets raised.

You can see why and how this is happening, in the django.template.response source code.

You can work around that problem by calling .render() manually on your response:

response = self.view(request)
self.assertEqual(response.status_code, status.HTTP_200_OK)

# Render the response manually
response.render()
json_dict = json.loads(response.content.decode('utf-8'))
self.assertEqual(json_dict['name'],instance.name)
like image 106
John Moutafis Avatar answered Sep 20 '22 13:09

John Moutafis