可以使用带有functool.partial绑定参数的Python mock.patch.object



如何解决此问题?用另一个签名(例如,一个额外的参数)修补一个对象方法。我试图绑定可选参数,但这似乎不起作用。我不能在这里使用普通的monkey修补,因为修补的类是在下面的一个位置调用的,否则我不能用这种方式修补它。

感谢您的帮助。

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)。

假设可以简单地进行monkey-patch,那么如果以实例作为第一个参数手动调用len,它就可以工作了。但这当然是不受欢迎的:

ToOverride.__len__ = my_len_bound
inst = ToOverride()
print( inst.__len__(inst)) # 2

通过使用闭包模式,可以避免使用functools partial,这对类方法不起作用。

def bind_arg(arg):
    def my_len(self, arg):
        return arg+1
    return my_len

老问题,但无论如何:使用functools.partialmethod 而不是functools.partial

如:

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

最新更新