I want to mock a function present inside a list and check whether it has been called at least once. Below is a similar implementation I tried:-
In fun_list.py (funA and funB are two functions in other_module)
import other_module
FUN_LIST = [
other_module.funA,
other_module.funB,
]
def run_funs():
for fun in FUN_LIST:
fun()
In demo.py
from fun_list import run_funs
def run_demo():
...
run_funs()
...
In test_demo.py
from demo import run_demo
@patch('other_module.funB')
def test_demo_funs(mocked_funB):
mocked_funB.return_value = {}
run_demo()
assert mocked_funB.called
In above case, I'm trying to mock funB in other_module but the function doesn't get mocked and the cursor gets inside the actual funB in other_module. Thus, the assert mocked_funB.called returns false.
Any lead on how I can mock other_module.funB ? I have found a similar question on StackOverflow but that went unanswered, so decided to post my version of it.
Any help will be appreciated, thank you in advance.
You need to mock before importing the module under test. The code in the module scope will be executed when import the module. It is too late to mock through the decorator when the test case is executed.
E.g.
other_module.py
:
def funA():
pass
def funB():
pass
fun_list.py
:
import other_module
print('execute module scope code')
FUN_LIST = [
other_module.funA,
other_module.funB,
]
def run_funs():
for fun in FUN_LIST:
fun()
demo.py
:
from fun_list import run_funs
def run_demo():
run_funs()
test_demo.py
:
import unittest
from unittest.mock import patch
class TestDemo(unittest.TestCase):
@patch('other_module.funB')
def test_demo_funs(self, mocked_funB):
print('mock before import the module')
from demo import run_demo
mocked_funB.return_value = {}
run_demo()
assert mocked_funB.called
if __name__ == '__main__':
unittest.main()
test result:
mock before import the module
execute module scope code
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
Name Stmts Miss Cover Missing
--------------------------------------------------------------------------
src/stackoverflow/67563601/demo.py 3 0 100%
src/stackoverflow/67563601/fun_list.py 6 0 100%
src/stackoverflow/67563601/other_module.py 4 1 75% 6
src/stackoverflow/67563601/test_demo.py 12 0 100%
--------------------------------------------------------------------------
TOTAL 25 1 96%