DRF测试:返回OrderedDict而不是JSON

时间:2015-02-25 14:59:54

标签: json django rest django-rest-framework

我正在尝试为Django Rest Framework实现测试。 我的大部分测试都通过并且设置得很顺利,但我现在遇到一个问题assertEqual永远不会成功,因为它一直在比较JSON和OrderedDict。

我不知道OrderedDict来自哪里,因为DRF 只返回JSON(对吧?)。

测试环境可能在比较之前解析JSON吗?那太糟糕了。

我正在进行集成测试,只测试GET请求对某个资源的响应中的数据,我是基于JSON fixture执行的。我没有测试REST框架的特定组件,因为我的组件实现非常简单,他们已经通过DRF项目中的测试进行了测试。

无论如何,我希望有人可以帮助我!

5 个答案:

答案 0 :(得分:7)

正如here所述,这是因为测试期间请求的默认格式为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.
}

自动修复所有测试。

答案 1 :(得分:2)

听起来你正在使用response.data(它返回解析的json对象)而不是response.content(它给出了原始的json字符串)。

请参阅http://www.django-rest-framework.org/api-guide/testing/#testing-responses

答案 2 :(得分:1)

如果你的测试看起来像这样:

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调用,专注于测试逻辑和正确的路由/视图/序列化器等。正在使用。

答案 3 :(得分:0)

您可以将数据转储为json格式 -

import json

返回HttpResponse(json.dumps(data))

答案 4 :(得分:0)

我通过使用SerializerMethodField解决了这个问题。

简单地,在序列化程序类中,复制下3行,并用引起问题的json成员替换result

class ConfigSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Config
        fields = ('id', 'url', 'email', "result",)

    # COPY NEXT 3 LINES AND CHANGE 'result' WITH THE JSON MEMBER THAT CAUSE THE PROBLEM
    result = serializers.SerializerMethodField()
    def get_result(self, obj):
        return obj.result

result显示为:

之前
{result: "OrderedDict([('key1', 1), ('key2', OrderedDict([('key3', [1, 2, 3])]))])"}

解决后,result变为:

{"result": {"key1":1,"key2":{"key3":[1,2,3]}}}