如何在Python中模拟函数以更改默认关键字参数
我正在使用mock库和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()
返回:
False
2 个回答
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
希望这对你有帮助
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]