Pytest monkeypatch对Flask视图函数不生效问题排查
解决Flask视图函数中Mock未生效的问题
这个问题我太熟悉了——本质是Python导入时的命名绑定在搞鬼!
问题根源
当你在views.py中使用from some_project.libraries.foo import create_foo时,Python会把create_foo函数的引用直接复制到some_project.views模块的命名空间里。你当前用monkeypatch修改的是原模块some_project.libraries.foo中的create_foo,但views.py里已经持有了原函数的引用,所以你的Mock根本没生效,原函数依然会执行并生成文件。
解决方案
有两种可行的修复方式,选一种适合你的即可:
方案1:Mock视图模块中已导入的引用(无需修改业务代码)
直接把monkeypatch的目标路径改成views模块里的create_foo引用:
def test_run(client, monkeypatch): # 修正:mock views模块内的create_foo引用 monkeypatch.setattr('some_project.views.create_foo', lambda: None) response = client.post('/run') assert b'Running' in response.data
方案2:修改业务代码的导入方式(更优雅)
在views.py中改为通过模块访问函数,避免直接导入带来的绑定问题:
# proj_root/some_project/views.py from some_project import APP from some_project.libraries import foo # 改为导入模块 @APP.route('/run', methods=['POST']) def run(): bar = foo.create_foo() # 通过模块调用函数 return 'Running'
这样你原来的monkeypatch代码就可以正常生效了,因为每次调用create_foo都会去原模块查找最新的引用。
内容的提问来源于stack exchange,提问作者Alex Waibel
相关产品推荐
相关产品推荐

