DRF-тестирование: вместо JSON возвращается OrderedDict

Я пытаюсь выполнить тесты для Django Rest Framework. Большинство моих тестов прошли, и их настройка прошла гладко, но теперь у меня проблема, когда assertEqual никогда не удается, потому что он продолжает сравнивать JSON с OrderedDict.

Я понятия не имею, откуда появился OrderedDict, поскольку DRF должен возвращать JSON (правильно?).

Возможно ли, чтобы среда тестирования анализировала JSON перед сравнением? Это сосать.

Я делаю интегрированный тест, который проверяет только данные в ответе запроса GET на определенный ресурс, я делаю это на основе JSON-светильников. Я не тестирую конкретный компонент REST-инфраструктуры, так как мои реализации компонентов настолько просты, что они уже тестировались в тестах в проекте DRF.

В любом случае, я надеюсь, кто-то может мне помочь!

Ответ 1

Как объясняется здесь, это связано с тем, что формат запросов по умолчанию во время тестов равен multipart вместо json. Вы можете указать формат, указав его на свой api-вызов следующим образом:

response = self.client.get('/something/1', format='json')

Или вы можете установить формат запроса по умолчанию в своем settings.py следующим образом:

REST_FRAMEWORK = {
    'TEST_REQUEST_DEFAULT_FORMAT': 'json',  # Use application/json instead of multipart/form-data requests in tests.
}

Автоматически исправить это для всех ваших тестов.

Ответ 2

Если ваши тесты выглядят примерно так:

class SomeTests(APITestCase):
    def test_something(self):
        response = self.client.get('/something/1')
        # assertions with response

Тогда ответ, безусловно, будет OrderedDict, а не JSON-документом. К счастью, Django 1.9 ввел метод response.json() (https://docs.djangoproject.com/en/1.9/topics/testing/tools/#django.test.Response.json), чтобы вы могли легко преобразовать ответ в JSON. Обратите внимание, что вы также можете использовать библиотеку python json.

Ловушка здесь заключается в том, что тестовый клиент Django (который расширяет DRF) является "фиктивным браузером" (https://docs.djangoproject.com/en/1.9/topics/testing/tools/#the-test-client) и не работать точно так же, как в браузере, например, Selenium. Таким образом, HTTP-вызовы на самом деле просто имитируют HTTP-вызовы, которые фокусируются на проверке вашей логики и правильной маршрутизации/просмотров/сериализаторов/и т.д. используются.

Ответ 4

Вы можете сбросить свои данные в json-форму -

import json

return HttpResponse (json.dumps(data))