Today I realized that it matters for unittest.mock.patch
how I import a function. Depending on the used way a mock.patch
call worked or was ignored. In Python we typically import a function with:
- an import statement like
import os
or - a
from ... import ...
statement likefrom os import system
A mock.patch
works like a charm if I use import os
, but it
was ignored if I patch a from os import system
.
Example 1: Using import
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()
Output of example 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!
Example 2: Using a full function import and from-import
When I fully import os.system
the mock.patch
ignores the 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!')
Output of example 2
<MagicMock name='system' id='139851175427376'>
Hello
Patch was ignored!
In both cases I don't receive an error and mock
could find os.system
as a valid path. However, in the second case the function is not properly patched.
- Why
mock.patch
does not patch the function in the second example? - Are there any implementation specific reasons why the second patch did not work?