模拟修补未从外部函数返回的内部函数的返回值



我想捕获内部函数的返回值,而不必显式地返回外部函数的返回值。

所以我想这样做:

# bar.py
import foo
def my_fn():
foo.fn()
# test.py
from mock import patch
import foo
import bar
@patch("foo.fn")
def test_bar(mock_foo_fn):
bar.my_fn()
# assert isinstance(mock_foo_fn.return_value, dict)

而不需要这样做:

# bar.py
import foo
def my_fn():
return foo.fn()

我有一个更干净的解决方案,使用spy

mocker.spy对象在所有情况下都与原始方法完全相同,除了间谍还跟踪函数/方法调用,返回值和引发的异常。

spy是由插件pytest-mockmocker夹具提供的。示例的用法演示:

# test.py
import pytest
import bar
def test_bar(mocker):
spy = mocker.spy(bar.foo, "fn")
bar.my_fn()
spy.assert_called_once_with()
assert spy.spy_return == {"k": "v"}

这可能比必要的更复杂,但我认为您需要用一个可调用对象来修补foo.fn,该对象捕获原始函数的返回值,而不仅仅是Mock。就像

class Wrapper:
def __init__(self, f):
self.f = f
def __call__(self, *args, **kwargs):
self.rv = self.f(*args, **kwargs)
with patch('foo.fn', new=Wrapper(foo.fn)) as m:
my_fn()
assert isinstance(m.rv, dict)

(使用with patch('foo.fn', wraps=foo.fn)之类的东西是不够的,因为虽然这样可以确保在调用mock时调用foo.fn本身,但mock本身不会捕获结果返回值。)

最新更新