[英]What is the reason that mock.patch ignores a fully imported function?
今天我意識到unittest.mock.patch
對於如何導入函數很重要。 根據使用的方式, mock.patch
調用工作或被忽略。 在Python中,我們通常導入一個函數:
import os
或 from os import system
的from ... import ...
語句 如果我使用import os
, mock.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
之前引用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')
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.