Flask应用pytest测试如何mock或绕过Cognito认证与群组权限校验
Flask路由Cognito校验的pytest mock方案
针对带Cognito认证装饰器的路由,有两种可落地的测试思路,分别对应完全绕过校验、模拟权限场景两种测试需求。
方案1:完全mock装饰器,绕过所有校验
适合只测试业务逻辑,不需要验证权限规则的场景。核心逻辑是在导入Flask应用前,mock两个Cognito装饰器,让它们直接返回原函数,等于跳过校验逻辑。
第一步:配置conftest.py
import pytest from unittest.mock import patch # 全局自动加载的fixture,在测试会话启动时优先执行 @pytest.fixture(scope="session", autouse=True) def mock_cognito_decorators(): # 注意:patch的路径要和你应用代码里导入装饰器的路径完全一致 # 示例路径是myapp.utils下的两个装饰器,请替换为你项目的实际导入路径 patch("myapp.utils.cognito_auth_required", lambda func: func).start() # 群组权限装饰器需要接收参数,所以多套一层lambda patch("myapp.utils.cognito_group_permissions", lambda *args, **kwargs: lambda func: func).start() yield # 测试结束后清空所有mock patch.stopall() # 测试客户端fixture @pytest.fixture def client(): # 必须在mock装饰器之后再导入应用,否则装饰器已经生效,mock不生效 from myapp import app app.config.update({"TESTING": True}) with app.test_client() as client: yield client
第二步:编写测试用例
def test_hello_route(client): resp = client.get("/hello") assert resp.status_code == 200 assert resp.data.decode() == "Hello, World"
方案2:mock权限逻辑,验证权限规则
适合需要测试不同用户组访问权限的场景,不需要调用真实Cognito服务,只模拟权限判断逻辑。
调整mock装饰器逻辑
修改conftest.py里的mock逻辑,加入自定义的权限判断:
def mock_group_check(allowed_groups): def decorator(func): def wrapper(*args, **kwargs): from flask import request # 从自定义请求头读取模拟的用户组信息 current_group = request.headers.get("X-Mock-User-Group", "") if current_group not in allowed_groups: return "Forbidden", 403 return func(*args, **kwargs) return wrapper return decorator @pytest.fixture(scope="session", autouse=True) def mock_cognito_decorators(): patch("myapp.utils.cognito_auth_required", lambda func: func).start() patch("myapp.utils.cognito_group_permissions", mock_group_check).start() yield patch.stopall()
权限场景测试用例
def test_hello_allowed(client): # 传入符合要求的用户组 resp = client.get("/hello", headers={"X-Mock-User-Group": "test"}) assert resp.status_code == 200 def test_hello_forbidden(client): # 传入不符合要求的用户组 resp = client.get("/hello", headers={"X-Mock-User-Group": "guest"}) assert resp.status_code == 403
注意事项
- mock的路径必须和你应用代码里导入装饰器的路径完全一致,比如你在app.py里用
from utils.auth import cognito_auth_required,那patch路径就应该是app.cognito_auth_required或者utils.auth.cognito_auth_required,根据你的项目结构调整 - 应用实例的导入必须放在mock执行之后,否则装饰器已经在路由上生效,mock不会生效
内容的提问来源于stack exchange,提问作者Jane Lane
相关产品推荐
相关产品推荐

