Django rest 框架:单元测试 post 请求获取状态码 400
Django rest framework: Unit testing post request gets status code 400
我正在这个餐厅应用程序中做一些单元测试,当 运行“manage.py 测试”命令时,API 请求取消订单 returns 代码 400 ,但在 Postman 上执行相同的请求工作正常(服务器也在我的本地计算机上 运行 使用“manage.py runserver”命令)。我认为这是我在单元测试中做错的事情,但我不确定。在设置中,Debug = True 和 ALLOWED_HOSTS = ['*'](但我也试过 ALLOWED_HOSTS = [])。这是代码:
tests.py
class CancelOrderAPITest(APITestCase):
def setUp(self):
test_product = Products.objects.create(id=1, name='testProduct', description='-test-', price=2.56)
test_product.save()
test_order = Order.objects.create(table=1, status='WA')
test_order.save()
test_order.product.add(test_product)
self.user = User.objects.create(username='test')
self.user.set_password('passtest')
self.user.save()
Payments.objects.create(value=0.0, user=self.user)
Token.objects.create(user=self.user)
def test_CancelWithCredentials(self):
check_login = self.client.login(username='test', password='passtest')
self.assertTrue(check_login)
token = Token.objects.get_or_create(user=self.user)
self.client.credentials(HTTP_AUTHORIZATION=f'Token {token[0].key}')
data = {"table": 1}
response = self.client.post(reverse('cancel-order'), data=data, content_type='application/json')
order = Order.objects.filter(table=data['table']).order_by('date')[0]
self.assertEqual(response.status_code, status.HTTP_200_OK) # returning 400. Investigate further
self.assertEqual(order.status, Order.Status.CANCELED)
views.py
class CancelOrder(APIView):
# REST API view for waiters to cancel orders. The waiter must be an authenticated user
permission_classes = (IsAuthenticated,)
parser_classes = (JSONParser,)
def post(self, request):
data = request.data
try:
order = Order.objects.filter(table=data['table']).order_by('date')[0]
order.status = Order.Status.CANCELED
order.save()
resp = {"status": "Order canceled!"}
except ObjectDoesNotExist:
resp = {"exception": "Couldn't find requested product!"}
return Response(resp)
models.py
class Order(models.Model):
class Status(models.TextChoices):
WAITING = 'WA', _('Waiting')
DELIVERED = 'DE', _('Delivered')
PARTIAL_DELIVER = 'PD', _('Partially Delivered')
PREPARING = 'PP', _('Preparing')
CANCELED = 'CA', _('Canceled')
PAID = 'PA', _('Paid')
product = models.ManyToManyField(Products)
table = models.IntegerField(default=1)
status = models.CharField(max_length=100, choices=Status.choices, default=Status.WAITING)
date = models.DateTimeField(default=datetime.datetime.now)
payment = models.ForeignKey(Payments, on_delete=models.DO_NOTHING, default=1)
感谢@annonymous 的评论,我明白了。
出于某种原因,单元测试在请求中使用单引号发送数据导致解析错误,即使我用双引号声明它也是如此。通过删除参数 content_type="application/json
并在请求中添加参数 format="json"
来解决。
我正在这个餐厅应用程序中做一些单元测试,当 运行“manage.py 测试”命令时,API 请求取消订单 returns 代码 400 ,但在 Postman 上执行相同的请求工作正常(服务器也在我的本地计算机上 运行 使用“manage.py runserver”命令)。我认为这是我在单元测试中做错的事情,但我不确定。在设置中,Debug = True 和 ALLOWED_HOSTS = ['*'](但我也试过 ALLOWED_HOSTS = [])。这是代码:
tests.py
class CancelOrderAPITest(APITestCase):
def setUp(self):
test_product = Products.objects.create(id=1, name='testProduct', description='-test-', price=2.56)
test_product.save()
test_order = Order.objects.create(table=1, status='WA')
test_order.save()
test_order.product.add(test_product)
self.user = User.objects.create(username='test')
self.user.set_password('passtest')
self.user.save()
Payments.objects.create(value=0.0, user=self.user)
Token.objects.create(user=self.user)
def test_CancelWithCredentials(self):
check_login = self.client.login(username='test', password='passtest')
self.assertTrue(check_login)
token = Token.objects.get_or_create(user=self.user)
self.client.credentials(HTTP_AUTHORIZATION=f'Token {token[0].key}')
data = {"table": 1}
response = self.client.post(reverse('cancel-order'), data=data, content_type='application/json')
order = Order.objects.filter(table=data['table']).order_by('date')[0]
self.assertEqual(response.status_code, status.HTTP_200_OK) # returning 400. Investigate further
self.assertEqual(order.status, Order.Status.CANCELED)
views.py
class CancelOrder(APIView):
# REST API view for waiters to cancel orders. The waiter must be an authenticated user
permission_classes = (IsAuthenticated,)
parser_classes = (JSONParser,)
def post(self, request):
data = request.data
try:
order = Order.objects.filter(table=data['table']).order_by('date')[0]
order.status = Order.Status.CANCELED
order.save()
resp = {"status": "Order canceled!"}
except ObjectDoesNotExist:
resp = {"exception": "Couldn't find requested product!"}
return Response(resp)
models.py
class Order(models.Model):
class Status(models.TextChoices):
WAITING = 'WA', _('Waiting')
DELIVERED = 'DE', _('Delivered')
PARTIAL_DELIVER = 'PD', _('Partially Delivered')
PREPARING = 'PP', _('Preparing')
CANCELED = 'CA', _('Canceled')
PAID = 'PA', _('Paid')
product = models.ManyToManyField(Products)
table = models.IntegerField(default=1)
status = models.CharField(max_length=100, choices=Status.choices, default=Status.WAITING)
date = models.DateTimeField(default=datetime.datetime.now)
payment = models.ForeignKey(Payments, on_delete=models.DO_NOTHING, default=1)
感谢@annonymous 的评论,我明白了。
出于某种原因,单元测试在请求中使用单引号发送数据导致解析错误,即使我用双引号声明它也是如此。通过删除参数 content_type="application/json
并在请求中添加参数 format="json"
来解决。