Django REST如何编写测试用例验证方法不被允许?
我来帮你搞定这个测试用例的问题!首先咱们得明确:你的OrderViewSet只继承了CreateModelMixin和GenericViewSet,也就是说只有**创建(POST)**接口是开放的,其他四个操作——列表查询、详情获取、部分更新、删除都应该返回405 Method Not Allowed状态码。下面是完整的测试实现,同时解决你提到的reverse()使用问题。
核心思路
- 利用Django REST Framework的
APITestCase来编写测试,它能方便地模拟HTTP请求 - 通过
reverse()生成正确的接口URL(关键是要匹配Router自动生成的URL名称) - 对每个被禁用的操作发送对应请求,断言返回状态码为405
完整测试代码
from django.urls import reverse from rest_framework.test import APITestCase from rest_framework import status from .models import Order # 导入你的Order模型 from .serializers import OrderSerializer # 导入你的序列化器 class OrderViewSetPermissionTests(APITestCase): def setUp(self): # 预先创建一个测试订单,用于详情、更新、删除测试 self.test_order = Order.objects.create( # 这里填写你的Order模型所需的字段,示例如下 total_amount=199.99, status="pending", customer_name="Test User" ) def test_list_orders_is_not_allowed(self): """测试列表查询(GET /orders/)不被允许""" # 生成列表接口的URL,名称由Router自动生成(前缀为orders时,名称是order-list) url = reverse("order-list") response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) def test_retrieve_order_is_not_allowed(self): """测试详情获取(GET /orders/<pk>/)不被允许""" url = reverse("order-detail", kwargs={"pk": self.test_order.pk}) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) def test_partial_update_order_is_not_allowed(self): """测试部分更新(PATCH /orders/<pk>/)不被允许""" url = reverse("order-detail", kwargs={"pk": self.test_order.pk}) update_data = {"status": "completed"} response = self.client.patch(url, update_data, format="json") self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) def test_delete_order_is_not_allowed(self): """测试删除操作(DELETE /orders/<pk>/)不被允许""" url = reverse("order-detail", kwargs={"pk": self.test_order.pk}) response = self.client.delete(url) self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)
解决reverse()的使用问题
你之前用reverse()出错,大概率是没匹配到正确的URL名称。Django REST Framework的Router会根据你注册的ViewSet自动生成URL名称:
- 如果你是这样注册的:
router.register(r'orders', OrderViewSet) - 那么列表接口的名称是
order-list,详情接口的名称是order-detail
不确定的话,可以直接运行以下命令查看所有注册的URL及对应名称:
python manage.py show_urls
额外注意事项
确保你的OrderViewSet配置了基础的queryset和serializer_class,否则可能会出现其他错误(虽然不影响405的断言,但规范配置能避免不必要的问题):
from rest_framework import viewsets, mixins from .models import Order from .serializers import OrderSerializer class OrderViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet): queryset = Order.objects.all() serializer_class = OrderSerializer
内容的提问来源于stack exchange,提问作者user2817219
相关产品推荐
相关产品推荐

