我想修改传递给模块中方法的参数,而不是替换它的返回值。
我已经找到了解决这个问题的方法,但这似乎是有用的东西,并且变成了嘲弄的一课。
from third_party import ThirdPartyClass
ThirdPartyClass.do_something('foo', 'bar')
ThirdPartyClass.do_something('foo', 'baz')
@mock.patch('module.ThirdPartyClass.do_something')
def test(do_something):
# Instead of directly overriding its return value
# I'd like to modify the arguments passed to this function.
# change return value, no matter inputs
do_something.return_value = 'foo'
# change return value, based on inputs, but have no access to the original function
do_something.side_effect = lambda x, y: y, x
# how can I wrap do_something, so that I can modify its inputs and pass it back to the original function?
# much like a decorator?
我尝试了类似下面的内容,但不仅重复而且难看,它不起作用。在进行了一些PDB内省之后..我想知道这是否仅仅是因为这个第三方库工作,因为我确实看到在side_effect
内放置pdb时原始函数被成功调用。
无论是那个,还是一些自动嘲笑的魔法,我只是没有遵循我想要了解的内容。
def test():
from third_party import ThirdPartyClass
original_do_something = ThirdPartyClass.do_something
with mock.patch('module.ThirdPartyClass.do_something' as mocked_do_something:
def side_effect(arg1, arg2):
return original_do_something(arg1, 'overridden')
mocked_do_something.side_effect = side_effect
# execute module.py
感谢任何指导!
答案 0 :(得分:17)
您可能希望使用参数wraps
进行模拟调用。 (Docs以供参考。)这样就可以调用原始函数,但它将包含Mock接口的所有内容。
因此,要更改调用原始函数的参数,您可能需要尝试这样:
#file org.py
def func(x):
print(x)
#file main.py
from unittest import mock
import org
of = org.func
def wrapped(a):
of('--{}--'.format(a))
with mock.patch('org.func', wraps=wrapped):
org.func('x')
org.func.assert_called_with('x')
结果:
--x--
答案 1 :(得分:0)
诀窍是将仍要访问的原始基础函数作为参数传递给该函数。
例如,为了进行竞赛条件测试,让tempfile.mktemp
返回一个现有路径名:
def mock_mktemp(*, orig_mktemp=tempfile.mktemp, **kwargs):
"""Ensure mktemp returns an existing pathname."""
temp = orig_mktemp(**kwargs)
open(temp, 'w').close()
return temp
以上,orig_mktemp
是在声明 时评估的,而不是在调用函数时评估的,因此所有调用都可以通过{{来访问tempfile.mktemp
的原始方法1}}。
我按如下方式使用它:
orig_mktemp