如何使用Django的assertJSONEqual来验证返回JsonResponse的视图的响应

时间:2014-12-14 18:38:18

标签: python django python-3.x django-testing jsonresponse

我正在使用Python 3.4和Django 1.7。我有一个返回JsonResponse的视图。

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

我想验证该视图是否使用单元测试返回正确的响应:

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'})

然而,assertJSONEqual()行引发了异常:

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'

当响应包含JSON时,检查响应内容的正确方法是什么?为什么当我尝试在assertJSONEqual()

中再次比较原始值时出现类型错误

2 个答案:

答案 0 :(得分:27)

您似乎正在使用Python 3,因此在将response.content传递给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'} ) 转换为UTF-8编码的字符串:

six

如果您想同时支持Python 2.7和Python 3,请使用django ships withfrom __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'} ) 兼容性库:

{{1}}

答案 1 :(得分:8)

与respondcreate的解决方案类似,您也可以使用Django的{{3}}(从1.5版开始提供),以获得更短的跨平台解决方案:

from __future__ import unicode_literals
from django.utils.encoding import force_text

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(force_text(response.content), {'status': 'success'})