Django 1.10 到 1.11 更新后如何修复测试
How to fix tests after Django 1.10 to 1.11 update
我正在开发一个使用 Django 1.10 和 DRF 3.6.4 的项目。当我将 Django 升级到 1.11 时,classes 中继承自 DRF APITestCase
的许多测试失败并出现以下错误:
AttributeError: 'HttpResponseBadRequest' object has no attribute 'data'
但是,在 Django 1.10 中,如果我尝试访问响应的不存在的属性,我会得到:
AttributeError: 'Response' object has no attribute 'ariel'
DRF 的测试客户端 extends Django's test client,所以我想 class 将其接口从 1.10 更改为 1.11,并且正在做一些魔术并返回这个新的实例 HttpResponseBadRequest
class,它没有 "data" 属性。但是,我没有在任何地方找到这些更改的记录,也没有在网上找到任何为此提出解决方案的讨论。有没有人知道必须更改什么以及在哪里可以找到新测试客户端界面的文档?
MCVE
views.py
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
class MyView(APIView):
def post(self, request, *args, **kwargs):
return Response({'error': 'My error message'}, status=status.HTTP_400_BAD_REQUEST)
urls.py
from django.conf.urls import url
from myapp import views
urlpatterns = [
url(r'^path/to/view/$', views.MyView.as_view(), name="my_url")
]
test_views.py
from rest_framework import status
from rest_framework.reverse import reverse
from rest_framework.test import APITestCase
class TestMyView(APITestCase):
def test_my_view(self):
response = self.client.post(
reverse('my_url'),
data={'some': 'data'},
format='json',
HTTP_HOST='host.com'
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.data['error'], "My error message")
# The line above passes in Django 1.10 and fails in 1.11
回溯
E
======================================================================
ERROR: test_my_view (myapp.tests.test_views.TestMyView)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/code/webapp/myapp/tests/test_views.py", line 14, in test_my_view
response.data['error'],
AttributeError: 'HttpResponseBadRequest' object has no attribute 'data'
终于找到罪魁祸首了。来自 Django 1.11 release notes:
ALLOWED_HOSTS validation is no longer disabled when running tests. If
your application includes tests with custom host names, you must
include those host names in ALLOWED_HOSTS. See Tests and multiple host
names.
我的 ALLOWED_HOSTS
中没有 'host.com'。我不知道为什么在测试期间明确发送了这个,因为甚至都没有检查设置。但这是一个有很多可疑代码的遗留项目,所以我不能说我真的很惊讶。
我还必须将项目中出现的所有 response.data
更改为 response.json()
。
我正在开发一个使用 Django 1.10 和 DRF 3.6.4 的项目。当我将 Django 升级到 1.11 时,classes 中继承自 DRF APITestCase
的许多测试失败并出现以下错误:
AttributeError: 'HttpResponseBadRequest' object has no attribute 'data'
但是,在 Django 1.10 中,如果我尝试访问响应的不存在的属性,我会得到:
AttributeError: 'Response' object has no attribute 'ariel'
DRF 的测试客户端 extends Django's test client,所以我想 class 将其接口从 1.10 更改为 1.11,并且正在做一些魔术并返回这个新的实例 HttpResponseBadRequest
class,它没有 "data" 属性。但是,我没有在任何地方找到这些更改的记录,也没有在网上找到任何为此提出解决方案的讨论。有没有人知道必须更改什么以及在哪里可以找到新测试客户端界面的文档?
MCVE
views.py
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
class MyView(APIView):
def post(self, request, *args, **kwargs):
return Response({'error': 'My error message'}, status=status.HTTP_400_BAD_REQUEST)
urls.py
from django.conf.urls import url
from myapp import views
urlpatterns = [
url(r'^path/to/view/$', views.MyView.as_view(), name="my_url")
]
test_views.py
from rest_framework import status
from rest_framework.reverse import reverse
from rest_framework.test import APITestCase
class TestMyView(APITestCase):
def test_my_view(self):
response = self.client.post(
reverse('my_url'),
data={'some': 'data'},
format='json',
HTTP_HOST='host.com'
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.data['error'], "My error message")
# The line above passes in Django 1.10 and fails in 1.11
回溯
E
======================================================================
ERROR: test_my_view (myapp.tests.test_views.TestMyView)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/code/webapp/myapp/tests/test_views.py", line 14, in test_my_view
response.data['error'],
AttributeError: 'HttpResponseBadRequest' object has no attribute 'data'
终于找到罪魁祸首了。来自 Django 1.11 release notes:
ALLOWED_HOSTS validation is no longer disabled when running tests. If your application includes tests with custom host names, you must include those host names in ALLOWED_HOSTS. See Tests and multiple host names.
我的 ALLOWED_HOSTS
中没有 'host.com'。我不知道为什么在测试期间明确发送了这个,因为甚至都没有检查设置。但这是一个有很多可疑代码的遗留项目,所以我不能说我真的很惊讶。
我还必须将项目中出现的所有 response.data
更改为 response.json()
。