如何为Python的@classmethod打补丁以调用自定义side_effect方法?
解决类方法打补丁时的TypeError问题
你遇到的报错是因为给类方法打补丁时,mock没有自动处理类方法的cls参数绑定逻辑。类方法原本会自动把所属类作为第一个参数(cls)传入,但直接用side_effect指定自定义方法时,如果不开启autospec=True,mock不会帮你自动传递这个参数,导致调用时出现TypeError。
修复方案一:开启autospec(推荐)
给类方法的patch.object加上autospec=True,让mock自动保留原类方法的签名,自动传入cls参数:
stack.enter_context( patch.object( SomeClass, "class_method", side_effect=class_method, autospec=True # 新增这个参数 ) )
修复方案二:修改mock方法的参数
如果不想用autospec,可以直接去掉mock方法里的cls参数(因为类方法调用时的cls参数不会被传递过来):
def class_method(): # 移除cls参数 print("mocked class_method")
完整修复代码(方案一)
from contextlib import ExitStack from unittest.mock import patch class SomeClass: def instance_method(self): print("instance_method") @staticmethod def static_method(): print("static_method") @classmethod def class_method(cls): print("class_method") # --- desired patch side effect methods ---- def instance_method(self): print("mocked instance_method") def static_method(): print("mocked static_method") def class_method(cls): print("mocked class_method") # --- Test --- obj = SomeClass() with ExitStack() as stack: stack.enter_context( patch.object( SomeClass, "instance_method", side_effect=instance_method, autospec=True ) ) stack.enter_context( patch.object( SomeClass, "static_method", side_effect=static_method, # autospec=True, ) ) stack.enter_context( patch.object( SomeClass, "class_method", side_effect=class_method, autospec=True # 开启autospec ) ) # 现在所有方法都能正常调用 obj.instance_method() obj.static_method() obj.class_method()
内容的提问来源于stack exchange,提问作者OldSchool
相关产品推荐
相关产品推荐

