下面的代码显示了该问题。
我可以成功地修补此SomeClass
的对象示例和静态方法
然而,我似乎无法修补类方法。
非常感谢帮助!
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
)
)
# These work
obj.instance_method()
obj.static_method()
# This fails with TypeError: class_method() missing 1 required positional argument: 'cls'
obj.class_method()
1条答案
按热度按时间oogrdqng1#
一般溶液
修补类方法的一种方法是使用
new=classmethod(class_method)
而不是side_effects=class_method
。这在总体上效果不错。
缺点
使用
new
,修补对象不再一定是Mock
、MagicMock
、AsyncMock
或PropertyMock
的示例(在答案的其余部分,我将只引用Mock
,因为所有其他都是它的子类)。只有当您通过
new=Mock(...)
或完全省略属性将其显式指定为一个属性时,它才是这些属性的示例。答案顶部提供的解决方案不会出现这种情况。因此,当您尝试检查函数是否已使用
obj.class_method.assert_called()
调用时,它会给予错误消息function has no attribute assert_called
,这是由于修补对象不是Mock
的示例,而是function
。遗憾的是,目前我看不到任何解决方案来解决这种情况下的不利因素
new
和side_effect
之间的结论差异:new
指定使用什么对象修补目标(不一定是Mock
的示例)side_effect
指定了Mock
示例的side_effect,该示例在使用没有new
的补丁时创建。此外,它们不能很好地配合使用,因此只能/应该在同一个patch(...)
中使用其中一个。