TypeError: unbound method when trying to mock a class

Scripts are not executed:

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', mocked_method): MyClass.my_method() 

An exception:

 Traceback (most recent call last): File "/home/foo/tmp/test_mocking_classmethod.py", line 14, in <module> MyClass.my_method() TypeError: unbound method mocked_method() must be called with MyClass instance as first argument (got nothing instead) 
+5
source share
1 answer

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 
+6
source

Source: https://habr.com/ru/post/1216004/


All Articles