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

Django单元测试中如何mock类视图挂载的自定义装饰器?

单元测试中Mock类视图方法装饰器的解决方案

核心逻辑:装饰器会在模块导入阶段就绑定到目标方法上,因此mock动作必须发生在视图模块导入前,或直接调用未被装饰的原始方法。

方案1:提前mock装饰器(推荐,适合全局批量处理)

该方案通过提前mock装饰器使其直接返回原函数,相当于装饰器完全不生效,后续导入的视图类不会被挂载认证逻辑:

from unittest.mock import patch
# 第一步:先mock装饰器,再导入视图模块
# 替换路径为你项目中authentication_decorator在视图里的引用路径
patch("your_app.views.authentication_decorator", side_effect=lambda func: func).start()

# 第二步:mock完成后再导入视图和依赖
from your_app.views import AddBlogView
from rest_framework.test import APITestCase

class AddBlogViewTest(APITestCase):
    def test_create_blog_success(self):
        # 正常编写业务测试逻辑即可
        test_data = {"title": "测试博客", "content": "测试内容"}
        response = self.client.post("/api/add_blog/", test_data, format="json")
        self.assertEqual(response.status_code, 201)

注意patch路径遵循「在哪里使用就在哪里patch」原则:如果你的视图文件是从common.decorators导入authentication_decorator,就需要patch视图模块内引用的这个装饰器,而不是直接patchcommon.decorators.authentication_decorator。

方案2:直接调用原始未装饰方法(适合单个测试用例临时绕过)

Python的装饰器默认会给原函数添加__wrapped__属性,存储未被装饰的原始函数,你可以在测试时直接替换视图类的post方法为原始方法:

from rest_framework.test import APITestCase
from your_app.views import AddBlogView

class AddBlogViewTest(APITestCase):
    def setUp(self):
        # 保存原方法,测试结束后恢复
        self.original_post = AddBlogView.post
        # 替换为未被装饰的原始方法
        AddBlogView.post = lambda self, request, *args, **kwargs: self.original_post.__wrapped__(self, request, *args, **kwargs)
    
    def tearDown(self):
        # 恢复原方法,避免影响其他测试用例
        AddBlogView.post = self.original_post

    def test_create_blog_success(self):
        test_data = {"title": "测试博客", "content": "测试内容"}
        response = self.client.post("/api/add_blog/", test_data, format="json")
        self.assertEqual(response.status_code, 201)

额外说明

  • 若使用pytest框架,可以把提前mock装饰器的逻辑写到conftest.py的会话级fixture中,全局生效无需重复编写。
  • 若需要保留装饰器但仅mock内部的HTTP请求逻辑,可以直接patch装饰器内部发送HTTP请求的方法,无需跳过整个装饰器。

内容的提问来源于stack exchange,提问作者Avik Pradhan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 18:36:03