出于测试目的,我想模拟shutil.which(Python 3.5.1),它在一个简化的方法中调用find_foo()
def _find_foo(self) -> Path:
foo_exe = which('foo', path=None)
if foo_exe:
return Path(foo_exe)
else:
return None
我正在使用pytest来实现我的测试用例 . 因此,我也想使用pytest扩展pytest-mock . 在下面我使用pytest pytest-mock粘贴了一个示例测试用例:
def test_find_foo(mocker):
mocker.patch('shutil.which', return_value = '/path/foo.exe')
foo_path = find_foo()
assert foo_path is '/path/foo.exe'
这种使用pytest-mock进行模拟的方法不起作用 . 仍然调用shutil.which而不是模拟 .
我试图直接使用mock包,它现在是Python3的一部分:
def test_find_foo():
with unittest.mock.patch('shutil.which') as patched_which:
patched_which.return_value = '/path/foo.exe'
foo_path = find_foo()
assert foo_path is '/path/foo.exe'
可悲的是结果是一样的 . 同时调用 shutil.which()
而不是指定的mock .
在我的测试用例中,哪些成功实现模拟的步骤是错误的或错过的?
3 回答
尝试使用monkeypatch . 您可以在示例中看到它们如何"monkeypatch"
os.getcwd
返回所需路径 . 在你的情况下,我认为这应该工作:将
which
方法注入到方法或对象中将允许您在没有pytest-mock
的情况下模拟依赖项 .我研究了更多时间学习unittest.mock和pytest-mock . 我找到了一个简单的解决方案,而没有使用补丁装饰器修改 生产环境 代码 . 在下面我粘贴了一个代码片段,展示了pytest-mock的第三种方法:
没有pytest-mock(plain unittest-mock和@patch装饰器),这个解决方案也可以工作 . 上面代码片段中的重要一行是
补丁装饰器需要函数的 name (完整路径),该函数将从被测系统调用 . mock documentation清楚地解释了这一点 . 以下段落总结了补丁装饰器的这个原理: