मैं एक कक्षा में किसी फ़ंक्शन में किए गए सभी फ़ंक्शन कॉल को रिकॉर्ड करने के लिए पैच का उपयोग करना चाहता हूं, लेकिन मूल फ़ंक्शन को अभी भी अपेक्षित रूप से चलाने की आवश्यकता है। मैंने नीचे एक डमी कोड उदाहरण बनाया है:

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() वर्ग का उदाहरण वास्तव में मुख्य कार्य में नहीं है बल्कि किसी अन्य मॉड्यूल में है, इसलिए मैं उदाहरण का मजाक नहीं उड़ा सकता। मुझे बी के सभी उदाहरणों के लिए सामान्य रूप से सजावटी होने की आवश्यकता है।

सारांश: मुझे यकीन नहीं है कि व्यक्तिगत रूप से क्लास विधि का स्वयं कैसे मजाक उड़ाया जाए, लेकिन फिर भी मूल विधि को कॉल करें। इसके बाद, मैं call_args_list जैसी किसी चीज़ का उपयोग करना चाहता हूं a> जहां मैं foo() को किए गए सभी कॉल देख सकता हूं।

15
mojo1mojo2 29 अप्रैल 2019, 10:33

2 जवाब

सबसे बढ़िया उत्तर

मुझे लगता है कि आप wraps नकली पैरामीटर ढूंढ रहे हैं। wraps के लिए आधिकारिक दस्तावेज खोजें। एक्सेस करने की विशेषताएँ एक नकली वस्तु लौटाती हैं लेकिन कॉलिंग विधियाँ वास्तविक विधि परिणाम देती हैं यदि नकली के लिए वापसी मान कॉन्फ़िगर नहीं किया गया है।

4
progmatico 2 मई 2019, 22:03

अधिक विवरण यहां पाया जा सकता है: 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()
1
pymen 23 मई 2020, 10:37