I have a class (ClassToBeMocked) that is instantiated in the init of another class (ContainerClass). I would like to mock the instantiated ClassToBeMocked and replace its dunder call method.
My code works for regular methods but not for the call dunder method.
from unittest.mock import patch, Mock, MagicMock
class ClassToBeMocked:
def __call__(self, x):
return 42
def regular_method(self, x):
return 42
class ContainerClass:
def __init__(self):
self.runner = ClassToBeMocked()
def run_a(self):
return self.runner(x="x")
def run_b(self):
return self.runner.regular_method(x="x")
with patch("__main__.ClassToBeMocked") as mock:
instance = mock.return_value
instance.__call__ = MagicMock(return_value="Hey")
instance.regular_method = MagicMock(return_value="Hey")
test = ContainerClass()
print(test.run_a())
print(test.run_b())
This outputs :
<MagicMock name='ClassToBeMocked()()' id='140033866116784'>
Hey
While I want to have
Hey
Hey
In the example below,
instance_cls()
does not callinstance_cls.__call__
. It callstype(instance_cls).__call__(instance_cls)
as python actually calls the__call__
method defined on the class, not the instance (for more information check this answer on stack overflow).Regarding you example, just change
instance.__call__ = MagicMock(return_value="Hey")
toinstance.__class__.__call__ = MagicMock(return_value="Hey")
and it should work.Full code below :