My code has the following structure:
I have a class MyClass
that inherits from BaseClass
(this is an incidental point and not the source of my problem). Then I have another class MyClassManager
that calls the methods of MyClass
.
I am writing a unittest for a method of MyClassManager
and I want to control the return value of one of the methods of MyClass
while autospeccing the rest.
In my test I have created a Mock for MyClass
by patching the class with autospec=True
. Then I have tried to patch the method MyClass.method_to_patch
and replace it with Substitute.substitute_method
. So far, so good.
But now when I run the test, the class manager creates an instance of MyClass
that is a fully autospecced Mock, but it doesn't patch the method I want to substitute.
Is there a way to combine these two patch
decorators to achieve what I want?
class Substitute:
def substitute_method(self, arg1, arg2):
print("Running substitute method")
return (arg1 > 0 and arg2 > 0)
class BaseClass:
def method_to_patch(self, arg1, arg2):
return arg1 == arg2
class MyClass(BaseClass):
def myclass_method(self):
print("myclass method called")
class MyClassManager:
def method_to_test(self):
my_class = MyClass()
my_class.myclass_method()
my_class.method_to_patch(10, 100)
class TestMyClass(unittest.TestCase):
@patch.object(MyClass, "method_to_patch", Substitute.substitute_method)
@patch("__main__.MyClass", autospec=True)
def test_method_to_test(self, mock_class):
class_manager = MyClassManager()
class_manager.method_to_test()
print(mock_class.call_count)
if __name__ == "__main__":
unittest.main()