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

如何在单元测试中禁用或Patch flask_of_oil的OAuthFilter装饰器

问题原因

Python的装饰器会在模块导入阶段执行,你代码里的@oauth.protect()在导入app.py的时候就已经运行完成,原接口方法已经被包装成了带认证校验逻辑的新方法。你后续再patchoauth.protect属性,只会影响patch之后新使用该装饰器的方法,不会改变已经完成装饰的接口逻辑,所以不生效。

解决方案

给你两种可选方案,按需选择:

方案1:测试侧直接mock校验逻辑(无需修改业务代码)

直接mock flask_of_oil内部的令牌校验核心方法,让所有校验直接返回合法结果,完全不需要修改原有app代码,修改后的test_foo.py如下:

import pytest
from unittest.mock import patch
from main.app import app

@pytest.fixture
def client():
    # mock令牌校验核心方法,无论输入什么都返回校验通过
    with patch('flask_of_oil.oauth_filter.OAuthFilter._introspect_token', return_value={"active": True}):
        with app.test_client() as client:
            yield client

def test_foo(client):
    response = client.get(path="/api/foo", follow_redirects=True)
    assert response.status_code == 200

方案2:业务代码加环境变量判断(逻辑更透明)

在app.py里新增环境变量判断逻辑,测试环境下直接返回空装饰器,修改后的app.py如下:

import os
from flask import Flask
from flask_restx import Api, Resource
from flask_of_oil.oauth_filter import OAuthFilter

# consts
OAUTH_HOST = "https://check.my.token/oauth2/introspect"
OAUTH_CLIENT = "client"
OAUTH_SECRET = "--secret--"

app = Flask(__name__)
api = Api(app=app)
oauth = OAuthFilter(verify_ssl=True)
namespace = api.namespace('api', description='AI & ML tools')

# 新增装饰器封装,测试环境直接跳过认证
def oauth_protect():
    if os.getenv("FLASK_ENV") == "test":
        return lambda func: func
    return oauth.protect()


@namespace.route('/foo')
class Foo(Resource):
    # 替换原来的@oauth.protect()
    @oauth_protect()
    @api.response(200, 'Success')
    @api.response(401, 'Unauthorized')
    @api.response(500, 'Unexpected Error')
    def get(self):
        return {'bar': 'foo'}


if __name__ == '__main__':
    oauth.configure_with_opaque(OAUTH_HOST, OAUTH_CLIENT, OAUTH_SECRET)
    app.run()

测试时只要提前设置环境变量FLASK_ENV=test即可自动跳过认证。

内容的提问来源于stack exchange,提问作者T. Moser

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 03:15:00