我想捕获内部函数的返回值,而不必显式地返回外部函数的返回值。
所以我想这样做:
# 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-mock
的mocker
夹具提供的。示例的用法演示:
# 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本身不会捕获结果返回值。)