如何在Python中模拟函数以更改默认关键字参数

时间:2013-01-30 13:43:30

标签: python mocking keyword-argument

我正在使用模拟库和unittest2来测试我的软件项目的不同方面。

目前我有以下问题:是否可以模拟一个函数,以便默认关键字参数不同,但功能仍然存在?

说我有以下代码

class C():
  def fun(self, bool_arg = True):
    if bool_arg:
      return True
    else
      return False

如果我想模仿C.fun怎么办?

C.fun = mock.Mock(???)

这样C的每个实例都会将关键字'bool_arg'替换为False,而不是True,结果为:

c = C()
c.fun()

返回:

  

2 个答案:

答案 0 :(得分:3)

您也可以尝试包装您的功能。

上的东西
def wrapper(func, bool_arg):
    def inner(*args, **kwargs):
        kwargs['bool_arg']=bool_arg
        return func(*args, **kwargs)
    return inner

class C():
    def fun(...):
        ...

c = C()
c.fun = wrapper(fun, False)

应该有效

修改

如果要更改类的默认值而不是特定实例,则可以创建派生类并重新定义fun包装C方法。在线的东西(我现在没有时间测试它):

class D(C):
    def fun(self, *args, **kwargs):
        f = wrapper(C.f, False)
        return f(*args, **kwargs)

然后关于@Ber的建议,你可以定义def wrapper(func, **wrapkwargs)然后代替kwargs['bool_arg']=bool_arg

for i in wrapkwargs.iteritems():  #wrapkwargs is a dictionary
    kwargs[i[0]] = i[1]

答案 1 :(得分:2)

您可以尝试使用此代码:

>>> import mock
>>> 
>>> class C():
...   def fun(self, bool_arg = True):
...     if bool_arg:
...       print "True"
...     else:
...       print "False"
... 
>>> c = C()
>>> funCopy = c.fun
>>> c.fun = mock.Mock(side_effect=lambda bool_arg=False: funCopy(bool_arg=bool_arg))
>>> c.fun()
False

希望这有帮助