簡體   English   中英

如何修補 python @classmethod 以調用我的 side_effect 方法?

[英]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 ,修補后的對象不再是MockMagicMockAsyncMockPropertyMock的實例(在剩下的回答中我將只引用Mock因為所有其他都是它的子類)。
只有當您通過例如new=Mock(...)明確指定它是一個或完全省略該屬性時,它才是這些的一個實例。
此答案頂部提供的解決方案並非如此。 因此,當您嘗試檢查函數是否已使用obj.class_method.assert_called()調用時,它會給出一個錯誤,指出該function has no attribute assert_called ,這是由於修補對象不是實例引起的的Mock ,而是一個function

不幸的是,目前我沒有看到任何解決方案來解決這種情況

newside_effect之間的結論差異:

  • new指定用什么對象來修補目標(不一定是Mock的實例)
  • side_effect指定在不使用new的情況下使用 patch 時創建的Mock實例的 side_effect 而且它們不能很好地協同工作,因此只能/應該在同一個patch(...)中使用其中一個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM