Как использовать assertJSONEqual в Django для проверки ответа представления, возвращающего 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 ответа
Похоже, вы работаете с Python 3, поэтому вам нужно включить response.content
в строку в кодировке UTF-8 перед передачей 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'}
)
Если вы хотите одновременно поддерживать Python 2.7 и Python 3, используйте six
библиотека совместимости, с которой поставляется django:
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'}
)
Точно так же, как и решение responsecreate, вы также можете использовать force_text Django (доступен с версии 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'})