![](/img/trans.png)
[英]python patch with side_effect on Object's method is not called with self
[英]How do I patch a python @classmethod to call my side_effect method?
下面的代码显示了这个问题。
我可以成功地修补这个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()
修补类方法的一种方法是使用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
指定在不使用new
的情况下使用 patch 时创建的Mock
实例的 side_effect 而且它们不能很好地协同工作,因此只能/应该在同一个patch(...)
中使用其中一个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.