python - 模拟 pytest 列表中存在的函数
问题描述
我想模拟一个存在于列表中的函数并检查它是否至少被调用过一次。下面是我尝试过的类似实现:-
在 fun_list.py 中(funA 和 funB 是 other_module 中的两个函数)
import other_module
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
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
在上述情况下,我试图在 other_module 中模拟 funB,但该函数没有被模拟,并且光标进入 other_module 中的实际 funB。因此,断言 mocked_funB.call 返回 false。
关于如何模拟 other_module.funB 的任何线索?我在 StackOverflow 上发现了一个类似的问题,但没有得到解答,因此决定发布我的版本。
任何帮助将不胜感激,在此先感谢您。
解决方案
您需要在导入被测模块之前进行模拟。模块范围内的代码将在导入模块时执行。执行测试用例时,通过装饰器模拟为时已晚。
例如
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()
测试结果:
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%
推荐阅读
- react-native - How to prevent navigation when navigating away from a component for React Native - web
- excel - 创建数据透视表的过程或调用无效
- image - image problems with matplotlib toolbar buttons
- php - How do I populate this placeholder info for a GoDaddy email form?
- c# - In C # how to change a value in a JObject, having the token in string format?
- java - Has conversion between Instant and Date changed from Java 8 to 11?
- javascript - On some pages don't show Menu Component but it is visible for a while
- batch-file - I am trying to add a line to the end of a concatinated txt file
- javascript - Sharepoint:如何根据搜索关键字过滤常见问题列表
- android - 创建的视图不在给定的坐标处