How do I unit test a monkey patch in Python

I have a utility method that behaves as follows

def my_patch_method(self): pass def patch_my_lib(): from mylib import MyClass MyClass.target_method = my_patch_method return MyClass() 

This test fails:

 self.assertEqual(my_patch_method, patch_my_lib().target_method) 

While this one works:

 self.assertEqual(my_patch_method.__name__, patch_my_lib().target_method.__name__) 

Since the patch method does not have the same name, this is still an acceptable proof that patch_my_lib() does what it paid for, but why is the first job not so expected? And is there a way to “fix” it?

+4
source share
4 answers

The reason your first test fails is because once you defuse a function in your class, it is not the same object.

 >>> def foo(self): pass ... >>> class Foo: pass ... >>> Foo.bar = foo >>> type(Foo.bar) <type 'instancemethod'> >>> type(foo) <type 'function'> >>> >>> Foo.bar is foo False >>> Foo.bar == foo False 

In fact, the original function and the new method are of different types. Instead, try checking this condition:

 >>> Foo.bar.im_func is foo True 

So maybe this is: self.assertIs(my_patch_method, patch_my_lib().target_method.im_func)

+3
source

Try:

 self.assertEqual(my_patch_method, patch_my_lib().target_method.im_func) 
+2
source

You are returning an instance from patch_my_lib, so comparing the function with the bound method

Something like this should pass

 self.assertEqual(my_patch_method, patch_my_lib().target_method.im_func) 

But it is probably best to verify that the behavior you are correcting works

+1
source

MyClass.target_method = my_patch_method sets the function as a class function for MyClass , but you return an instance of this class using return MyClass() .

0
source

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


All Articles