Python Patch/Mock class method but still call original method

I think you are looking for the wraps Mock parameter. Search the official documentation for wraps. Accessing attributes returns a mock object. Calling methods gives the real method result instead, if a return value is not configured for the mock.


More details can be found here: 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()

Just keep a reference to your original, non-mocked/patched instance around.

I had an issue that I was patching ctypes.windll.winmm.mciSendStringW, but I still wanted to be able to access that original function. Initially, I had tried:

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!

The correct thing to do was actually this... since it was the function being mocked/patched, it was the function that I needed to keep a reference to.

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!

Tags:

Python

Mocking