Python中mock.assert_has_calls的适用场景及使用疑问
关于
mock.assert_has_calls的用途说明 它不是用来防止Python解释器替换你的调用对象(解释器不会干这种事),核心作用是验证你的代码确实按照预期的顺序、参数,调用了mock对象指定的次数。
核心适用场景
- 当你的代码会多次调用同一个mock对象,需要验证所有调用的参数和顺序是否符合预期
- 当你需要确认某个mock对象被调用的完整调用序列,而不只是最后一次调用
和assert_called_with的区别
assert_called_with只能检查mock对象最后一次调用的参数是否正确,而assert_has_calls可以检查所有调用的参数和顺序:
- 默认会严格校验调用顺序
- 可以通过
any_order=True参数,忽略顺序只验证所有指定的调用是否都发生过
举个实际例子
假设你有这样的业务代码:
def process_data(): # 预期先调用Foo(1),再调用Foo(2) Foo(1) Foo(2)
测试时你mock了Foo,用assert_has_calls验证调用流程:
from unittest.mock import Mock # 初始化mock对象 Foo = Mock() # 执行业务逻辑 process_data() # 验证调用序列:先传1,再传2 Foo.assert_has_calls([ Mock.call(1), Mock.call(2) ])
如果源码里出现以下情况,这个断言会失败:
- 把第二个
Foo(2)改成了Bar(2)——此时Foo只被调用了1次,不符合预期的2次调用 - 调用顺序搞反,变成先
Foo(2)再Foo(1)——默认顺序校验不通过 - 参数写错,比如第二个调用是
Foo(3)——参数不符合预期
总结
它的本质是测试你的业务逻辑的调用行为是否符合设计预期,而非检查Python解释器的执行错误。比如你设计流程需要调用Foo两次,参数分别是1和2,用这个方法就能确保代码确实遵循了这个流程。
内容的提问来源于stack exchange,提问作者rumble_shark
相关产品推荐
相关产品推荐

