Python pytest中如何查找Mock对象send方法的调用位置?
定位Mock对象send方法调用位置的解决方案
- 方案1:通过抛异常打印调用栈(最直接)
在创建Mock对象后、传入被测代码前,给send方法绑定抛异常的side_effect:
from mock import Mock mocked_class = Mock() # 新增这一行 mocked_class.send.side_effect = RuntimeError("捕获send调用") # 后续原测试逻辑不变
运行测试后,异常的栈回溯会直接显示调用send方法的代码行位置。
- 方案2:不中断测试打印调用栈
如果不想中断测试运行,可以用inspect模块输出完整调用栈:
import inspect from mock import Mock def track_send_call(*args, **kwargs): print("=== send被调用,调用栈如下 ===") for frame in inspect.stack()[1:]: print(f"文件:{frame.filename}, 行号:{frame.lineno}, 函数:{frame.function}") # 保留Mock的原有行为,不影响测试逻辑 return Mock() mocked_class = Mock() mocked_class.send.side_effect = track_send_call
运行测试后控制台会输出所有调用send的上下文位置。
- 方案3:排查Mock实例是否被正确注入
如果上述两个方案都没有触发,说明你断言的mocked_class并不是实际被测代码调用的实例:- 检查测试代码中是否有多处创建同类型Mock、或者重新给被注入变量赋值的逻辑
- 可以分别打印当前测试里的
id(mocked_class)和被测代码中接收该实例的变量id,确认是否为同一个对象 - 查看
mocked_class.mock_calls属性,会列出该Mock对象所有被调用的方法、参数和顺序,辅助确认send是否真的被当前实例接收
补充说明:你之前直接赋值
mocked_class.send=my_method不生效的原因是Mock的属性是懒加载的,只有首次访问时才会生成对应的子Mock实例,如果赋值时机晚于被测代码首次访问send的时机,自定义方法不会生效,使用内置的side_effect配置可以规避这个问题。
内容的提问来源于stack exchange,提问作者Ehud Lev
相关产品推荐
相关产品推荐

