![](/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.