【问题标题】:DRF Response content-type set to None during testsDRF 响应内容类型在测试期间设置为无
【发布时间】:2018-01-23 08:37:33
【问题描述】:

我正在使用 Django Rest Framework(版本 3.6.2)来创建 REST API。我已经定义了从GenericViewSet 继承的视图集,并重写了retrieve 方法来实现自定义行为。

class FooViewSet(viewsets.GenericViewSet):
    serializer_class = FooSerializer

    def retrieve(self, request, *args, **kwargs):
        ... 
        serializer = self.get_serializer(data)
        return Response(serializer.data)

我希望在从浏览器访问此端点时拥有 BrowsableAPI,并在访问此端点时收到 json 响应,例如从代码。我已经使用以下设置配置了 DRF:

    REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ),
    'TEST_REQUEST_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
    ),
    'TEST_REQUEST_DEFAULT_FORMAT':'json'
}

一切都按预期工作,我可以从浏览器访问可浏览的 API,当使用 Postman 工具发出请求时,我会收到 json 响应。不幸的是,我在测试期间无法获得相同的结果。

class GetFooDetailViewTest(APITestCase):

    def test_get_should_return_json(self):
        response = self.client.get(self.VIEW_URL)
        self.assertEqual(response.content_type, "application/json")

我希望响应的 content_type 设置为 application/json(这是我可以在浏览器和 Postman 的响应中看到的标题)。但此测试失败 - response.content_type 设置为 None。在调试这个测试时,我发现response._headers 字典看起来像这样

{
    'vary': ('Vary', 'Cookie'),
    'x-frame-options': ('X-Frame-Options', 'SAMEORIGIN'),
    'content-type': ('Content-Type', 'application/json'),
    'allow': ('Allow', 'GET, PUT, DELETE, OPTIONS')
}

所以似乎设置了正确的标题,但它没有填充到content_type 属性。我错过了什么吗?

【问题讨论】:

    标签: python json django django-rest-framework django-rest-viewsets


    【解决方案1】:

    这就是我测试内容类型的方式。在极少数情况下,我的代码本身决定了内容类型,所以我要检查我个人没有做错什么。 DRF 代码已经过测试。

    self.assertEqual("application/json", resp['Content-Type'])
    

    您只需要依靠 DRF 来做正确的事情,这不是您可以或需要测试的东西。例如,您没有测试 DRF 是否正确解析了您的 json 正文。测试服务器与真实服务器不完全相同,但非常接近。例如,您将从 response.data 中获取 real 对象,而不是 json 编码/解码的对象。

    如果需要,请查看LiveServerTestCase,但它会更慢。

    【讨论】:

    • 它可以工作,但请记住,您只是在重新测试已经测试过的代码。响应对象中的内容类型稍后会正确转换为文本。
    • 是的,我知道,谢谢。我认为这是一个非常简单的测试,并且可以在未来检测到不需要的/无意的配置更改,所以恕我直言,将它包含在我的测试套件中并没有什么不好。你怎么看?
    • 它不会受到伤害,并且可以防止破坏您自己的项目设置:)
    【解决方案2】:

    我遇到了类似的事情,这对我有用:

    response = self.client.get(self.VIEW_URL, HTTP_ACCEPT='application/json')

    【讨论】:

      猜你喜欢
      • 2015-03-10
      • 2011-07-26
      • 1970-01-01
      • 2012-04-20
      • 1970-01-01
      • 2022-11-16
      • 2021-04-20
      • 2010-12-12
      • 2016-12-05
      相关资源
      最近更新 更多