如果从列表中调用,则不会模拟 python 函数 [英] python function not mocked if called from list
问题描述
当从函数列表中调用函数时,我试图模拟该函数.
以下有效:
# demo_module.py导入 demo_module_bdef run_me():run_me_too()
# demo_module_bdef run_me_too():经过
# test.py从 demo_module 导入 run_me从 demo_module_b 导入 run_me_too@patch('demo_module_b.run_me_too')def test_run_me_with_patch(mock_run_me_too):运行_我()断言 mock_run_me_too. called # PASSES
以下失败:
# demo_module.py导入 demo_module_b过程 = [demo_module_b.run_me_too,]def run_me():进程[0]()
# demo_module_bdef run_me_too():经过
# test.py从 demo_module 导入 run_me从 demo_module_b 导入 run_me_too@patch('demo_module_b.run_me_too')def test_run_me_with_patch(mock_run_me_too):运行_我()断言 mock_run_me_too. called # 失败
有没有办法在不需要模拟列表的情况下让它工作?
编辑 1
这也失败了(并且直接导入两个测试都失败了):
# demo_module.py从 demo_module_b 导入 run_me_too进程 = [run_me_too,]def run_me():processes[0]() # 测试失败run_me_too() # 在测试中也失败
您需要在导入被测模块之前进行模拟.导入模块时将执行模块范围内的代码.测试用例执行时通过装饰器进行模拟已经太晚了.
例如
demo_module.py
:
import demo_module_b过程 = [demo_module_b.run_me_too,]def run_me():进程[0]()
demo_module_b.py
:
def run_me_too():经过
test_demo_module.py
:
import unittest从 unittest.mock 导入补丁类 TestDemoModule(unittest.TestCase):@patch('demo_module_b.run_me_too')def test_run_me_with_patch(self, mock_run_me_too):从 demo_module 导入 run_me运行_我()断言 mock_run_me_too.call如果 __name__ == '__main__':单元测试.main()
测试结果:
<预><代码>.----------------------------------------------------------------------在 0.002 秒内运行 1 次测试好的Name Stmts Miss Cover Missing-------------------------------------------------------------------------------src/stackoverflow/61774393/demo_module.py 4 0 100%src/stackoverflow/61774393/demo_module_b.py 2 1 50% 2src/stackoverflow/61774393/test_demo_module.py 10 0 100%-------------------------------------------------------------------------------总计 16 1 94%I am trying to mock a function when the function is called from a list of functions.
The below works:
# demo_module.py
import demo_module_b
def run_me():
run_me_too()
# demo_module_b
def run_me_too():
pass
# test.py
from demo_module import run_me
from demo_module_b import run_me_too
@patch('demo_module_b.run_me_too')
def test_run_me_with_patch(mock_run_me_too):
run_me()
assert mock_run_me_too.called # PASSES
The below fails:
# demo_module.py
import demo_module_b
PROCESS = [
demo_module_b.run_me_too,
]
def run_me():
PROCESSES[0]()
# demo_module_b
def run_me_too():
pass
# test.py
from demo_module import run_me
from demo_module_b import run_me_too
@patch('demo_module_b.run_me_too')
def test_run_me_with_patch(mock_run_me_too):
run_me()
assert mock_run_me_too.called # FAILS
Is there a way to get this to work without needing to mock the list to?
Edit 1
This also fails (And importing directly fails both tests):
# demo_module.py
from demo_module_b import run_me_too
processes = [
run_me_too,
]
def run_me():
processes[0]() # FAILS IN TEST
run_me_too() # ALSO FAILS IN TEST
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.
demo_module.py
:
import demo_module_b
PROCESSES = [
demo_module_b.run_me_too,
]
def run_me():
PROCESSES[0]()
demo_module_b.py
:
def run_me_too():
pass
test_demo_module.py
:
import unittest
from unittest.mock import patch
class TestDemoModule(unittest.TestCase):
@patch('demo_module_b.run_me_too')
def test_run_me_with_patch(self, mock_run_me_too):
from demo_module import run_me
run_me()
assert mock_run_me_too.called
if __name__ == '__main__':
unittest.main()
test result:
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
Name Stmts Miss Cover Missing
------------------------------------------------------------------------------
src/stackoverflow/61774393/demo_module.py 4 0 100%
src/stackoverflow/61774393/demo_module_b.py 2 1 50% 2
src/stackoverflow/61774393/test_demo_module.py 10 0 100%
------------------------------------------------------------------------------
TOTAL 16 1 94%
这篇关于如果从列表中调用,则不会模拟 python 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!