如何对Python MagicMock的链式成员调用进行断言校验?
报错原因
你代码里foo.bar.baz指向的是foo对象下bar属性自带的baz属性,但你实际执行的是foo.bar()调用返回的MagicMock实例的baz方法,二者是完全独立的两个MagicMock实例,因此对foo.bar.baz做断言必然失败。
MagicMock的调用链返回的新实例都会挂载到上一级方法的return_value属性上,同时顶层Mock的mock_calls列表会完整记录全链路调用。
解决方案
方案1:直接校验顶层Mock的调用记录
使用assert_has_calls方法直接匹配mock_calls里的全链路调用记录,不需要单独获取各级返回值:
from unittest.mock import MagicMock, call foo = MagicMock() foo.bar().baz() # 断言调用链符合预期,any_order=False表示要严格匹配调用顺序 foo.assert_has_calls([ call.bar(), call.bar().baz() ], any_order=False)
小提示:如果要校验调用时传入的参数,直接在
call的括号里填写预期参数即可,比如call.bar(123, name="test")。
方案2:通过return_value获取子实例单独断言
如果不需要校验全链路,只想单独确认某一级子方法被调用,可以顺着return_value拿到实际被调用的子Mock实例做断言:
from unittest.mock import MagicMock foo = MagicMock() foo.bar().baz() # 断言bar方法被调用 foo.bar.assert_called_once() # 断言bar返回值的baz方法被调用 foo.bar.return_value.baz.assert_called_once()
如果是更长的调用链,比如foo.a().b().c(),断言c被调用的写法为:
foo.a.return_value.b.return_value.c.assert_called_once()
两种方案都不需要提前手动创建各级Mock实例,直接用MagicMock自动生成的实例即可完成断言。
内容的提问来源于stack exchange,提问作者Haterind
相关产品推荐
相关产品推荐

