Python mock.patch.object 可以使用 functool.partial 绑定参数吗?

问题描述 投票:0回答:3

如何解决这个问题?用另一个签名(例如,一个附加参数)修补对象方法。我尝试绑定可选参数,但这似乎不起作用。我不能在这里使用简单的猴子修补,因为修补的类是在否则我无法以这种方式修补它的位置。

任何帮助表示赞赏。

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
python mocking optional-parameters monkeypatching functools
3个回答
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

1
投票

通过使用闭包模式,可以避免使用 functoolspartial,它不适用于类方法。

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

0
投票

将call_args的str与expected_call进行比较 例如

self.assertEqual( str(running_loop.run_in_executor.call_args), 字符串( 称呼( process_pool.进入(), functools.partial(_my_fun, arg1, arg2), ) ), )

© www.soinside.com 2019 - 2024. All rights reserved.