如何在pytest中绕过Flask接口的auth_required装饰器进行单元测试
在pytest中绕过Flask接口的auth_required装饰器进行单元测试
以下是几种可行的解决方案,针对你的场景逐一说明:
方法1:直接调用视图函数的__wrapped__属性
你之前误用了response.__wrapped__,正确的做法是直接获取视图函数本身的__wrapped__属性(因为@wraps(fn)会保留原函数的引用),绕过装饰器直接执行核心逻辑。
实现代码:
from your_module import organisationcontroller # 导入你的蓝图模块 def test_organisations_happy_path(): # 直接调用被装饰器包裹的原视图函数 result = organisationcontroller.get_organisations.__wrapped__() # 验证返回结果的结构和内容 assert "organisations" in result assert isinstance(result["organisations"], list)
注意:这种方式不需要使用
app_client,因为是直接调用函数而非发起HTTP请求,适合纯逻辑单元测试。
方法2:使用unittest.mock.patch替换auth_required装饰器
通过patch把auth_required替换成一个不做验证、直接返回原函数的装饰器,这样在测试时装饰器会被完全跳过。
实现代码:
from unittest.mock import patch from your_module import app # 导入你的Flask app实例 def test_organisations_happy_path(app_client): # 定义一个mock装饰器,直接返回原函数 def mock_auth_required(roles): def wrapper(fn): return fn return wrapper # patch掉auth_required装饰器,路径要指向你定义该装饰器的模块 with patch("your_module.auth_required", side_effect=mock_auth_required): # 重新加载蓝图确保patch生效 from your_module import organisationcontroller app.register_blueprint(organisationcontroller) # 正常发起请求,此时装饰器已被替换 response = app_client.get('/organisations') assert response.status_code == 200 assert "organisations" in response.json
方法3:给装饰器添加测试模式开关
修改你的auth_required装饰器,让它在测试环境下自动跳过验证,这种方式不需要修改测试代码,更优雅。
修改后的装饰器代码:
from functools import wraps from flask import current_app def auth_required(roles): def wrapper(fn): @wraps(fn) def decorator(*args, **kwargs): # 如果是测试环境,直接跳过验证 if current_app.config.get("TESTING"): return fn(*args, **kwargs) # 原有的JWT角色验证逻辑 # ...(你的验证代码) return fn(*args, **kwargs) return decorator return wrapper
测试代码(无需额外修改):
def test_organisations_happy_path(app_client): # 测试环境下TESTING配置默认是True,装饰器会自动跳过验证 response = app_client.get('/organisations') assert response.status_code == 200
注意:确保你的Flask app在测试时已开启
TESTING模式,通常pytest fixture里会配置:import pytest from your_module import app @pytest.fixture def app_client(): app.config["TESTING"] = True with app.test_client() as client: yield client
内容的提问来源于stack exchange,提问作者Gary Frewin
相关产品推荐
相关产品推荐

