无法使用 TestCase 库对 Django APIviews 进行单元测试?
Unable to unittest Django APIviews with TestCase library?
这是一个非常具体的项目问题,但我不知道我做错了什么。我有一个视图 class 允许用户对项目数据库执行 GET 和 POST 请求。我能够成功地 GET/POST 使用 curl,但是当我为此编写单元测试时,我无法让它通过测试,我也不完全理解为什么。
此命令有效:
curl http://127.0.0.1:8000/list/categories/ -d '{"id":"00001", "name":"some info"}'
view.py:
class CategoryList(APIView):
def get(self, request, format=None):
categories = Category.objects.all()
serializer = CategorySerializer(categories, many=True)
context = {
'categories': categories
}
return render(request, 'myapp/categories.html', context)
def post(self, request, format=None):
print('=======inside post=========')
data = JSONParser().parse(request)
serializer = CategorySerializer(data=data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
urls.py:
urlpatterns = [
# eg: /list/categories/
url(r'^categories/$', CategoryList.as_view()),
]
这是我的测试失败的地方。
tests.py:
class CategoryViewTests(TestCase):
def setUp(self):
""" Mock model data """
cat1 = Category.objects.create(id=55555, name="Shoes")
cat2 = Category.objects.create(id=12345, name="Wallets")
def test_new_unique_category(self):
"""
Create a new category obj
"""
c = Client()
print(str(Category.objects.all()))
new_cat_data = {'id':'54211', 'name':'Soccer Balls'}
response = c.post('/list/categories', new_cat_data)
print(str(Category.objects.all()))
self.assertEqual(response.status_code, 201)
终端输出:
test_new_unique_category (inferbrand.tests.CategoryViewTests) ...
<QuerySet [<Category: Test Men's Shoes>, <Category: Test Wallets>]>
<QuerySet [<Category: Test Men's Shoes>, <Category: Test Wallets>]>
FAIL
======================================================================
FAIL: test_new_unique_category (inferbrand.tests.CategoryViewTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "path/to/proj/tests.py", line 104, in test_new_unique_category
self.assertEqual(response.status_code, 201)
AssertionError: 301 != 201
我做错了什么??任何帮助将不胜感激。
curl 命令有效,因为你在 URL 中有一个尾部斜杠,但在你的单元测试中 URL 没有尾部斜杠,所以 Django 将它重定向到 URL 带有状态代码 301 的尾部斜杠,这是默认行为,除非您在 settings.py
.
中将 APPEND_SLASH
设置为 False
详情请参考https://docs.djangoproject.com/en/2.0/ref/settings/#append-slash
好的。我认为根本原因是序列化程序无法正确处理来自 django unittests 的传入请求。我最终删除了所有序列化程序,而是像这样替换它们:
class CategoryList(APIView):
def get(self, request, format=None):
categories = Category.objects.all()
context = {
'categories': categories
}
return render(
request,
'myapp/categories.html',
context
)
def post(self, request, format=None):
data = request.POST
new_cat = Category(id=data['id'],
name=data['name'])
new_cat.save()
return HttpResponseRedirect(reverse('myapp:category_detail', args=[ new_cat.id ]))
新的卷曲格式:
curl http://127.0.0.1:8000/list/categories/ -d 'id=1299988&name=Tennis123'
post HttpResponseRedirect 仍然无法正常工作,(returns 状态 301),但 POST/GET 现在可以使用 curl 和单元测试,这是我遇到的主要问题。
这是一个非常具体的项目问题,但我不知道我做错了什么。我有一个视图 class 允许用户对项目数据库执行 GET 和 POST 请求。我能够成功地 GET/POST 使用 curl,但是当我为此编写单元测试时,我无法让它通过测试,我也不完全理解为什么。
此命令有效:
curl http://127.0.0.1:8000/list/categories/ -d '{"id":"00001", "name":"some info"}'
view.py:
class CategoryList(APIView):
def get(self, request, format=None):
categories = Category.objects.all()
serializer = CategorySerializer(categories, many=True)
context = {
'categories': categories
}
return render(request, 'myapp/categories.html', context)
def post(self, request, format=None):
print('=======inside post=========')
data = JSONParser().parse(request)
serializer = CategorySerializer(data=data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
urls.py:
urlpatterns = [
# eg: /list/categories/
url(r'^categories/$', CategoryList.as_view()),
]
这是我的测试失败的地方。
tests.py:
class CategoryViewTests(TestCase):
def setUp(self):
""" Mock model data """
cat1 = Category.objects.create(id=55555, name="Shoes")
cat2 = Category.objects.create(id=12345, name="Wallets")
def test_new_unique_category(self):
"""
Create a new category obj
"""
c = Client()
print(str(Category.objects.all()))
new_cat_data = {'id':'54211', 'name':'Soccer Balls'}
response = c.post('/list/categories', new_cat_data)
print(str(Category.objects.all()))
self.assertEqual(response.status_code, 201)
终端输出:
test_new_unique_category (inferbrand.tests.CategoryViewTests) ...
<QuerySet [<Category: Test Men's Shoes>, <Category: Test Wallets>]>
<QuerySet [<Category: Test Men's Shoes>, <Category: Test Wallets>]>
FAIL
======================================================================
FAIL: test_new_unique_category (inferbrand.tests.CategoryViewTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "path/to/proj/tests.py", line 104, in test_new_unique_category
self.assertEqual(response.status_code, 201)
AssertionError: 301 != 201
我做错了什么??任何帮助将不胜感激。
curl 命令有效,因为你在 URL 中有一个尾部斜杠,但在你的单元测试中 URL 没有尾部斜杠,所以 Django 将它重定向到 URL 带有状态代码 301 的尾部斜杠,这是默认行为,除非您在 settings.py
.
APPEND_SLASH
设置为 False
详情请参考https://docs.djangoproject.com/en/2.0/ref/settings/#append-slash
好的。我认为根本原因是序列化程序无法正确处理来自 django unittests 的传入请求。我最终删除了所有序列化程序,而是像这样替换它们:
class CategoryList(APIView):
def get(self, request, format=None):
categories = Category.objects.all()
context = {
'categories': categories
}
return render(
request,
'myapp/categories.html',
context
)
def post(self, request, format=None):
data = request.POST
new_cat = Category(id=data['id'],
name=data['name'])
new_cat.save()
return HttpResponseRedirect(reverse('myapp:category_detail', args=[ new_cat.id ]))
新的卷曲格式:
curl http://127.0.0.1:8000/list/categories/ -d 'id=1299988&name=Tennis123'
post HttpResponseRedirect 仍然无法正常工作,(returns 状态 301),但 POST/GET 现在可以使用 curl 和单元测试,这是我遇到的主要问题。