如何解决这个问题?用另一个签名(例如,一个附加参数)修补对象方法。我尝试绑定可选参数,但这似乎不起作用。我不能在这里使用简单的猴子修补,因为修补的类是在否则我无法以这种方式修补它的位置。
任何帮助表示赞赏。
import mock
import functools
# this class lives in another (unchangeable) module, __len__ method has to be patched
class ToOverride(object):
def __len__(self):
raise NotImplementedError()
# this code is changeable
def my_len(self, arg):
return arg+1
my_len_bound = functools.partial(my_len, arg=1)
with mock.patch.object(ToOverride, '__len__', my_len_bound):
inst = ToOverride()
print len(inst) # expected output: 2
调用上下文mock.patch.object时,出现以下错误:
TypeError Traceback (most recent call last)
<ipython-input-7-bfdb41d8628f> in <module>()
1 with mock.patch.object(ToOverride, '__len__', my_len_bound):
2 inst = ToOverride()
----> 3 print len(inst)
TypeError: my_len() takes exactly 2 arguments (1 given)
但是使用 None 作为第一个参数调用 my_len 可以按预期工作(打印出 2)。
假设可以简单地进行猴子修补,如果使用实例作为第一个参数手动调用 len,它就可以工作。但这当然是不受欢迎的:
ToOverride.__len__ = my_len_bound
inst = ToOverride()
print( inst.__len__(inst)) # 2
老问题,但无论如何:不要使用
functools.partial
,而是使用 functools.partialmethod
如:
from unittest import mock
import functools
class ToOverride(object):
def __len__(self):
raise NotImplementedError()
def my_len(self, arg):
return arg+1
my_len_bound = functools.partialmethod(my_len, arg=1)
with mock.patch.object(ToOverride, '__len__', my_len_bound):
inst = ToOverride()
assert len(inst) == 2
通过使用闭包模式,可以避免使用 functoolspartial,它不适用于类方法。
def bind_arg(arg):
def my_len(self, arg):
return arg+1
return my_len
将call_args的str与expected_call进行比较 例如
self.assertEqual( str(running_loop.run_in_executor.call_args), 字符串( 称呼( process_pool.进入(), functools.partial(_my_fun, arg1, arg2), ) ), )