DRF 响应 content-type 在测试期间设置为 None
DRF Response content-type set to None during tests
我正在使用 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 的响应中看到的 header)。但是这个测试失败了——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')
}
所以似乎设置了正确的 header,但它没有填充到 content_type
属性。我错过了什么吗?
这就是我测试内容类型的方式。在极少数情况下,我的代码本身决定内容类型,所以我要检查我 个人 没有做错什么。 DRF 代码已经过测试。
self.assertEqual("application/json", resp['Content-Type'])
你只需要依靠 DRF 做对,它不是你可以或不需要测试的东西。例如,您没有测试 DRF 是否正确解析了您的 json 正文。测试服务器与真实服务器不完全相同,但非常接近。例如,您将从 response.data 中得到 真实的 个对象,而不是 json encoded/decoded 个对象。
如果需要可以查看LiveServerTestCase,但是速度会慢一些。
我 运行 喜欢类似的东西,这对我有用:
response = self.client.get(self.VIEW_URL, HTTP_ACCEPT='application/json')
我正在使用 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 的响应中看到的 header)。但是这个测试失败了——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')
}
所以似乎设置了正确的 header,但它没有填充到 content_type
属性。我错过了什么吗?
这就是我测试内容类型的方式。在极少数情况下,我的代码本身决定内容类型,所以我要检查我 个人 没有做错什么。 DRF 代码已经过测试。
self.assertEqual("application/json", resp['Content-Type'])
你只需要依靠 DRF 做对,它不是你可以或不需要测试的东西。例如,您没有测试 DRF 是否正确解析了您的 json 正文。测试服务器与真实服务器不完全相同,但非常接近。例如,您将从 response.data 中得到 真实的 个对象,而不是 json encoded/decoded 个对象。
如果需要可以查看LiveServerTestCase,但是速度会慢一些。
我 运行 喜欢类似的东西,这对我有用:
response = self.client.get(self.VIEW_URL, HTTP_ACCEPT='application/json')