Django rest framework: Юнит-тестирование пост-запрос получает код состояния 400
Я делаю несколько модульных тестов в приложении для ресторана, и запрос API на отмену заказов возвращает код 400 при выполнении команды "manage.py test", но тот же запрос на 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}
order = Order.objects.filter(table=data['table']).order_by('date')[0]
response = self.client.post(reverse('cancel-order'), data=data, content_type='application/json')
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. По какой-то причине модульный тест отправлял данные в запрос в одинарных кавычках, что приводило к ошибке разбора, хотя я объявлял их в двойных кавычках. Добавление следующей строки перед отправкой запроса решило эту проблему:
data = json.dumps(data)