I have two classes like below:
in parent.py:
class TestClassParent(ABC):
def test_method(self):
print('the method TestMethod is called')
return True
in child.py:
from src.scripts.parent import TestClassParent
class TestClassChild(TestClassParent):
custom_vars = [1, 2, 3]
I have a test class for child.py called, child_test.py like this:
from unittest import TestCase
from unittest.mock import patch
from src.scripts.child import TestClassChild
class ChildTest(TestCase):
@patch('src.scripts.child.TestClassParent', autospec=True)
def test(self, mock_parent_class):
mock_parent_class.return_value.test_method.return_value = False
i = TestClassChild()
a = i.test_method()
assert a is False
Looks like the patch @patch('src.scripts.child.TestClassParent', autospec=True)
didn't work and when a = i.test_method()
is executed, the actual implementation is run.
However mocking an individual methods of the TestClassParent
works as expected for example if I change the implementation like below, it works fine:
@patch('src.scripts.child.TestClassParent.test_method', autospec=True)
def test(self, mock_method):
mock_method.return_value = False
i = TestClassChild()
a = i.test_method()
assert a is False
I also read from pytest - Patching a class does not work, calls class instead that I should mock the class where it's used not where it's defined and I did it exactly like that, the TestClassParent
was used inside TestClassChild
so I mocked where it's used: @patch('src.scripts.child.TestClassParent')
but no luck.
I even mocked both TestClassChild
and TestClassParent
(both the usage and definition) still no luck and also removed autospec=True
but again no luck.
Any ideas ??
Any help would be hugely appreciated.
I think you may be assuming an incorrect resolution order.
The modules are imported and therefore the class relationships defined before the patch ever occurs.
What you're targeting by mocking all methods of a parent class that propagate through children can probably be done through meta programming, although it would likely be sort of hacky -- so I wouldn't recommend it.
Another solution could be to alter the classes to utilize dependency injection, but if it were me, I would simply mock the instances as needed and call it a day.
This link may provide further clarification -- https://stackoverflow.com/a/38928265/13261176