gpt4 book ai didi

python - mock.patch 忽略完全导入的函数的原因是什么?

转载 作者:太空宇宙 更新时间:2023-11-03 15:42:52 24 4
gpt4 key购买 nike

今天我意识到如何导入函数对 unittest.mock.patch 很重要。根据使用的方式,mock.patch 调用有效或被忽略。在 Python 中,我们通常导入一个函数:

  • 导入语句,如 import os
  • from ... import ... 语句,如 from os import system

如果我使用 import osmock.patch 就像一个魅力,但它如果我修补 from os import system 则被忽略。

示例 1:使用导入

import os
from unittest import mock


def echo():
os.system('echo "Hello"')


with mock.patch('os.system') as mocked:
print(mocked)
mocked.side_effect = Exception('Patch works!')
echo()

示例 1 的输出

<MagicMock name='system' id='140037358656760'>

Traceback (most recent call last):
File "/.../config/scratches/scratch_7.py", line 12, in <module>
echo()
File "/.../config/scratches/scratch_7.py", line 6, in echo
os.system('echo "Hello"')
File "/.../python3.5/unittest/mock.py", line 917, in __call__
return _mock_self._mock_call(*args, **kwargs)
File "/.../python3.5/unittest/mock.py", line 973, in _mock_call
raise effect
Exception: Patch works!

示例 2:使用全功能导入和自导入

当我完全导入 os.system 时,mock.patch 会忽略 mocked.side_effect

from os import system
from unittest import mock


def echo():
system('echo "Hello"')


with mock.patch('os.system') as mocked:
print(mocked)
mocked.side_effect = Exception('Patching does not work!')
echo()

print('Patch was ignored!')

示例 2 的输出

<MagicMock name='system' id='139851175427376'>
Hello
Patch was ignored!

在这两种情况下,我都没有收到错误,mock 可以找到 os.system 作为有效路径。但是,在第二种情况下,该功能未正确修补。

  • 为什么 mock.patch 没有给第二个例子中的函数打补丁?
  • 是否有任何具体实现原因导致第二个补丁不起作用?

最佳答案

当你执行 from os import system 时,你会得到一个名为 system 的变量,指向 os.system 函数。稍后,您通过修补分配一个不同的函数给os.system,但system 保持指向旧函数。这与以下工作的原因相同:

tmp = a
a = b
b = tmp

在第一个示例中没有发生,因为您在模拟之前引用了 os.system。要修复您的第二个示例,我将采用以下方法:

from os import system
from unittest import mock

def echo():
system('echo "Hello"')

with mock.patch('__main__.system') as mocked:
print(mocked)
mocked.side_effect = Exception('Patching does not work!')
echo()

print('Patch was ignored!')

这样您就可以确保修补正确的引用。这是一种相当常见的模式。如果 echo 函数位于名为 echo.py 的文件中,则补丁调用将类似于 with mock.patch('echo.system') .

关于python - mock.patch 忽略完全导入的函数的原因是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51614538/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com