Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Django's assertJSONEqual to verify response of view returning JsonResponse

I'm using Python 3.4 and Django 1.7. I have a view returning JsonResponse.

def add_item_to_collection(request):     #(...)     return JsonResponse({'status':'success'}) 

I want to verify if that view returns correct response using unit test:

class AddItemToCollectionTest(TestCase):      def test_success_when_not_added_before(self):         response = self.client.post('/add-item-to-collection')         self.assertEqual(response.status_code, 200)         self.assertJSONEqual(response.content, {'status': 'success'}) 

However the assertJSONEqual() line raises an exception:

Error Traceback (most recent call last):   File "E:\Projects\collecthub\app\collecthub\collecting\tests.py", line 148, in test_success_when_added_before     self.assertJSONEqual(response.content, {'status': 'OK'})   File "E:\Projects\collecthub\venv\lib\site-packages\django\test\testcases.py", line 675, in assertJSONEqual     data = json.loads(raw)   File "C:\Python34\Lib\json\__init__.py", line 312, in loads     s.__class__.__name__)) TypeError: the JSON object must be str, not 'bytes' 

What is thet correct way of checking content of response, when response contains JSON? Why i get type error when i try to compare raw value agains a dict in assertJSONEqual() ?

like image 417
Mariusz Jamro Avatar asked Dec 14 '14 18:12

Mariusz Jamro


People also ask

What does the Django's JsonResponse do?

Django JsonResponse JsonResponse is an HttpResponse subclass that helps to create a JSON-encoded response. Its default Content-Type header is set to application/json. The first parameter, data , should be a dict instance.

How do I return a JSON response?

To return JSON from the server, you must include the JSON data in the body of the HTTP response message and provide a "Content-Type: application/json" response header. The Content-Type response header allows the client to interpret the data in the response body correctly.


1 Answers

It looks like you're working with Python 3 so you'll need to turn response.content into a UTF-8 encoded string before passing it to self.assertJSONEqual:

class AddItemToCollectionTest(TestCase):      def test_success_when_not_added_before(self):         response = self.client.post('/add-item-to-collection')         self.assertEqual(response.status_code, 200)         self.assertJSONEqual(             str(response.content, encoding='utf8'),             {'status': 'success'}         ) 

If you want to simultaneously support both Python 2.7 and Python 3, use the six compatibility library that django ships with:

from __future__ import unicode_literals from django.utils import six  class AddItemToCollectionTest(TestCase):      def test_success_when_not_added_before(self):         response = self.client.post('/add-item-to-collection')         self.assertEqual(response.status_code, 200)          response_content = response.content         if six.PY3:             response_content = str(response_content, encoding='utf8')          self.assertJSONEqual(             response_content,             {'status': 'success'}         ) 
like image 64
respondcreate Avatar answered Oct 08 '22 21:10

respondcreate