簡體   English   中英

Python Patch/Mock 類方法但仍調用原始方法

[英]Python Patch/Mock class method but still call original method

我想使用補丁來記錄對類中的函數進行的所有函數調用以進行單元測試,但需要原始函數仍按預期運行。 我在下面創建了一個虛擬代碼示例:

from mock import patch

class A(object):
    def __init__(self):
        self._a = 1

class B(A):
    def __init__(self):
        super(B, self).__init__() # TypeError: super() argument 1 must be type, not MagicMock
        self._b = 11

    def bar(self, b):
        self._b = self._b + 1 + b

    def foo(self, b):
        self.bar(b)

class MockB(B):
    def foo(self, b):
        super(MockB, self).foo(self, b)

@patch('main.B')
def main(b_class):
    b_class.side_effect = MockB

    b = B()

    print b._b # 11
    b.foo(0)
    print b._b # 12

main()

就我而言,類b = B()的實例實際上不在主函數中,而是在另一個模塊中,因此我無法模擬該實例。 我需要它一般作為 B 的所有實例的裝飾器。

總結:我不確定如何單獨模擬類方法,但仍然調用原始方法。 之后,我想使用call_args_list 之類的東西,在那里我可以看到對foo()所有調用。

我認為您正在尋找wraps Mock 參數。 在官方文檔中搜索wraps 訪問屬性返回一個模擬對象。 如果沒有為模擬配置返回值,則調用方法會給出真實的方法結果。

更多細節可以在這里找到: https : //stackoverflow.com/a/61963740/1731460

import mock
from contextlib import contextmanager


@contextmanager
def mock_patch_method_original(mock_path, original_method, results):
    results = iter(results)

    def side_effect(self, *args, **kwargs):
        value = next(results)
        if value == '__original__':
            side_effect.self = self
            return original_method(self, *args, **kwargs)
        else:
            return value

    patcher = mock.patch(mock_path, autospec=True, side_effect=side_effect)
    yield patcher.start()
    patcher.stop()

只需保留對您原始的、非模擬/修補的實例的引用。

我在修補ctypes.windll.winmm.mciSendStringW遇到了一個問題,但我仍然希望能夠訪問該原始函數。 最初,我曾嘗試過:

from ctypes import windll
originalWindll = windll

# Later on trying to call the original mciSendStringW when it's patched...
originalWindll.winmm.mciSendStringW(...)  # Didn't work! Called the patched version of the function!

正確的做法實際上是這樣...因為它是被模擬/修補的函數,所以我需要保留對它的引用。

from ctypes import windll
originalMCISendStringW = windll.winmm.mciSendStringW

# Later on trying to call the original mciSendStringW when it's patched...
originalMCISendStringW(...)  # Works! Calls the original, non-patched version of this function!

暫無
暫無

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

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