How to mock an import
You can assign to sys.modules['B']
before importing A
to get what you want:
test.py:
import sys
sys.modules['B'] = __import__('mock_B')
import A
print(A.B.__name__)
A.py:
import B
Note B.py does not exist, but when running test.py
no error is returned and print(A.B.__name__)
prints mock_B
. You still have to create a mock_B.py
where you mock B
's actual functions/variables/etc. Or you can just assign a Mock()
directly:
test.py:
import sys
sys.modules['B'] = Mock()
import A
The builtin __import__
can be mocked with the 'mock' library for more control:
# Store original __import__
orig_import = __import__
# This will be the B module
b_mock = mock.Mock()
def import_mock(name, *args):
if name == 'B':
return b_mock
return orig_import(name, *args)
with mock.patch('__builtin__.__import__', side_effect=import_mock):
import A
Say A
looks like:
import B
def a():
return B.func()
A.a()
returns b_mock.func()
which can be mocked also.
b_mock.func.return_value = 'spam'
A.a() # returns 'spam'
Note for Python 3:
As stated in the changelog for 3.0, __builtin__
is now named builtins
:
Renamed module
__builtin__
tobuiltins
(removing the underscores, adding an ‘s’).
The code in this answer works fine if you replace __builtin__
by builtins
for Python 3.