Python functions are descriptors , and Python associates them with the instance they are viewing, or in the case of classmethod , the class. Since you did not use the classmethod decorator in the replacement function, it is mistakenly bound (like a regular method, therefore, cls is not passed).
Just wrap the target in the classmethod decorator manually:
with mock.patch.object(MyClass, 'my_method', classmethod(mocked_method)): MyClass.my_method()
Here I applied the @classmethod decorator manually, but you can also just use it as intended, like a decorator, directly in the target function:
@classmethod def mocked_method(cls): print('I want this method to get called') with mock.patch.object(MyClass, 'my_method', mocked_method): MyClass.my_method()
Demo:
>>> import mock >>> class MyClass(object): ... @classmethod ... def my_method(cls): ... print('my_method') ... >>> def mocked_method(cls): ... print('I want this method to get called') ... >>> with mock.patch.object(MyClass, 'my_method', classmethod(mocked_method)): ... MyClass.my_method() ... I want this method to get called
source share