You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为带有IsAuthenticated权限的Django REST API端点编写单元测试

问题根因
  • reverse函数用法错误:reverse仅用于根据路由名称生成URL路径,仅接收路由定义的路径参数作为入参,你把登录请求的业务参数(邮箱、密码)传入reverse的kwargs中,自然找不到匹配的路由,触发NoReverseMatch报错。
  • model_bakery创建的用户密码为加密哈希值:直接读取self.user.password拿到的是加密后的密文,无法作为明文密码请求登录接口。
  • 认证前缀不匹配:SimpleJWT默认的认证前缀为Bearer,你代码中使用的Token前缀会被认证中间件判定为无效。
  • 冗余代码:自定义的apiclient未被使用,属于无效代码。
解决方案

提供两种可选方案,可根据你的测试场景选择:

方案1:修正原有逻辑,完整走JWT认证流程

适合需要同时验证登录+业务接口的集成测试场景:

from rest_framework.test import APITestCase
from model_bakery import baker
from django.urls import reverse

class TranslationTestCases(APITestCase):
    def setUp(self):
        self.role = baker.make(Roles)
        # 创建用户并手动设置明文可登录密码
        self.user = baker.make(Users, user_role=self.role)
        self.test_pwd = "test_verify_123"
        self.user.set_password(self.test_pwd)
        self.user.save()
        self.translation = baker.make(Translation, _quantity=10)
    
    def test_get_all_translations(self):
        # 先请求token接口获取access凭证
        token_url = reverse('token_obtain_pair')
        token_resp = self.client.post(
            token_url,
            data={"email": self.user.email, "password": self.test_pwd},
            format="json"
        )
        access_token = token_resp.data["access"]
        # 携带token请求目标接口,使用SimpleJWT默认的Bearer前缀
        response = self.client.get(
            reverse('display_translation'),
            HTTP_AUTHORIZATION=f"Bearer {access_token}"
        )
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 10)

方案2:强制认证,跳过JWT申请流程(推荐单元测试使用)

如果仅需要测试翻译接口的业务逻辑,不需要校验登录流程,直接用DRF测试工具自带的强制认证方法即可,代码更简洁高效:

from rest_framework.test import APITestCase
from model_bakery import baker
from django.urls import reverse

class TranslationTestCases(APITestCase):
    def setUp(self):
        self.role = baker.make(Roles)
        self.user = baker.make(Users, user_role=self.role)
        self.translation = baker.make(Translation, _quantity=10)
        # 直接给测试客户端绑定登录状态,无需请求token接口
        self.client.force_authenticate(user=self.user)
    
    def test_get_all_translations(self):
        response = self.client.get(reverse('display_translation'))
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 10)

内容的提问来源于stack exchange,提问作者Saad Mrabet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 05:57:04