如何通过Mock补丁为指定类的requests.Session请求添加认证参数
解决方案:仅为特定第三方类的请求添加基础认证
你的现有代码问题在于patch路径错误,且未对请求发起者做区分。以下是两种可行的实现方案,无需修改第三方库代码:
方案一:通过调用栈识别调用者,动态添加认证
利用inspect模块追踪调用栈,判断发起请求的实例是否属于目标类,仅对FirstClass的请求追加认证参数。
from unittest.mock import patch import requests import inspect class FirstClass: def make_request(self, url, headers=None): with requests.Session() as session: response = session.get(url, headers=headers) return response class SecondClass: def make_request(self, url, headers=None): with requests.Session() as session: response = session.get(url, headers=headers) return response def patched_get(self, url, **kwargs): # 遍历调用栈,找到发起请求的类实例 stack = inspect.stack() for frame_info in stack: local_vars = frame_info.frame.f_locals if 'self' in local_vars: caller_instance = local_vars['self'] # 仅为FirstClass的请求添加基础认证 if isinstance(caller_instance, FirstClass): kwargs['auth'] = ('your_username', 'your_password') break # 调用原始的get方法执行请求 return original_get(self, url, **kwargs) # 保存原始的Session.get方法 original_get = requests.Session.get # 测试时patch requests.Session.get with patch.object(requests.Session, 'get', side_effect=patched_get): first = FirstClass() second = SecondClass() # FirstClass的请求会自动携带认证 first.make_request("https://httpbin.org/basic-auth/your_username/your_password") # SecondClass的请求无认证 second.make_request("https://httpbin.org/status/200")
方案二:Patch Session构造,针对目标类返回带认证的Session
替换requests.Session的构造逻辑,当检测到是FirstClass创建Session时,自动为其设置认证属性,后续所有请求都会携带认证信息。
from unittest.mock import patch import requests import inspect class FirstClass: def make_request(self, url, headers=None): with requests.Session() as session: response = session.get(url, headers=headers) return response class SecondClass: def make_request(self, url, headers=None): with requests.Session() as session: response = session.get(url, headers=headers) return response def patched_session(): session = requests.Session() # 追踪调用栈判断创建Session的实例所属类 stack = inspect.stack() for frame_info in stack: local_vars = frame_info.frame.f_locals if 'self' in local_vars: caller_instance = local_vars['self'] if isinstance(caller_instance, FirstClass): session.auth = ('your_username', 'your_password') break return session # 测试时patch requests.Session构造方法 with patch('requests.Session', side_effect=patched_session): first = FirstClass() second = SecondClass() first.make_request("https://httpbin.org/basic-auth/your_username/your_password") second.make_request("https://httpbin.org/status/200")
注意事项
- 调用栈遍历逻辑可根据第三方库的实际代码结构调整,确保能准确识别
FirstClass的调用上下文。 - 若目标类使用了其他请求方法(如
post),只需对对应的Session.post方法做同样的patch处理即可。
内容的提问来源于stack exchange,提问作者Auggers
相关产品推荐
相关产品推荐

