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!