Python 模拟pytest中列表中的函数

Python 模拟pytest中列表中的函数,python,unit-testing,pytest,python-unittest,python-mock,Python,Unit Testing,Pytest,Python Unittest,Python Mock,我想模拟列表中的函数,并检查它是否至少被调用过一次。下面是我尝试过的类似实现:- 在fun\u list.py中(funA和funB是其他模块中的两个函数) 在demo.py中 from fun_list import run_funs def run_demo(): ... run_funs() ... from demo import run_demo @patch('other_module.funB') def test_demo_funs(mocked_f

我想模拟列表中的函数,并检查它是否至少被调用过一次。下面是我尝试过的类似实现:-

在fun\u list.py中(funA和funB是其他模块中的两个函数)

在demo.py中

from fun_list import run_funs

def run_demo():
    ...
    run_funs()
    ...
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
from fun_list import run_funs

def run_demo():
    ...
    run_funs()
    ...
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
在test\u demo.py中

from fun_list import run_funs

def run_demo():
    ...
    run_funs()
    ...
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
from fun_list import run_funs

def run_demo():
    ...
    run_funs()
    ...
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
在上面的例子中,我试图模拟其他_模块中的funB,但函数没有被模拟,光标进入了其他_模块中的实际funB。因此,assert mocked_funB.called返回false

有关于我如何模仿其他模块的线索吗? 我在StackOverflow上发现了类似的问题,但没有得到回答,所以决定发布我的版本


任何帮助都将不胜感激,提前感谢。

在导入测试中的模块之前,您需要进行模拟。导入模块时将执行模块作用域中的代码。在执行测试用例时,通过decorator进行模拟已经太迟了

例如

其他模块.py

def funA():
通过
def funB():
通过
fun\u list.py

导入其他_模块
打印('执行模块范围代码')
乐趣清单=[
其他(u module.funA),
其他_module.funB,
]
def run_funs():
在乐趣列表中寻找乐趣:
乐趣
demo.py

从乐趣列表导入运行乐趣
def run_demo():
run_funs()
测试\u demo.py

导入单元测试
从unittest.mock导入修补程序
类TestDemo(unittest.TestCase):
@补丁('other_module.funB')
def测试演示功能(自嘲功能):
打印('导入模块前模拟')
从演示导入运行\u演示
mocked_funB.return_value={}
运行_demo()
断言mocked_funB.called
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
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%
我从中起了带头作用,并对事情做了一些不同的修改。在我的例子中,我有多个这样的测试函数,它们模拟funB并调用run_demo(最初是来自Django.test的client.post()调用)。如果先前的函数调用成功,则其他后续修补程序将失败(原因与@slideshowp2所述相同)。所以,我改变了这个方法:-

在fun\u list.py中(funA和funB是其他模块中的两个函数)

在demo.py中

from fun_list import run_funs

def run_demo():
    ...
    run_funs()
    ...
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
from fun_list import run_funs

def run_demo():
    ...
    run_funs()
    ...
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
在test\u demo.py中

from fun_list import run_funs

def run_demo():
    ...
    run_funs()
    ...
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
from fun_list import run_funs

def run_demo():
    ...
    run_funs()
    ...
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

您好@slideshowp2,非常感谢。这无疑消除了我对此的困惑。我会接受这个答案。最后一个查询,我有多个这样的测试函数,它们模拟funB并调用run_demo()。如果前面的函数成功调用它,那么其他后续修补程序将失败(可能是因为与您提到的相同的原因)。这方面有什么解决方案吗?在我的例子中,运行_demo()的调用实际上是一个client.post()调用,使用@pytest.mark.django_db decorator@Mr\u某人,你最好用最小的、可复制的示例问一个新问题Sure@slideshowp2