我想修改传递给模块中方法的参数,而不是替换其返回值。

我已经找到了解决此问题的方法,但它似乎很有用,并且已成为模拟类(class)。

module.py

from third_party import ThirdPartyClass

ThirdPartyClass.do_something('foo', 'bar')
ThirdPartyClass.do_something('foo', 'baz')

tests.py
@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内省(introspection)之后。我想知道这是否仅是由于该第三方库起作用而引起的,因为我确实看到了将dbt放入side_effect时成功调用了原始功能。

要么,要么是一些自动 mock 的魔术,我只是没有遵循我想学习的知识。
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

任何指导表示赞赏!

最佳答案

您可能要使用参数wraps进行模拟调用。 (请参阅Docs。)这样,将调用原始函数,但它将具有Mock接口(interface)中的所有内容。

因此,对于更改调用为原始函数的参数,您可能需要这样尝试:

org.py :

def func(x):
    print(x)

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

关于python - 有没有办法在模拟的方法/函数中访问原始函数,以便我可以修改参数并将其传递给原始函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30336828/

10-12 16:46
查看更多