在__name__ == "__main__"中patch MyAPI无效,用法是否正确?
问题分析与修复
你的patch('common.apis.MyAPI', mock_api)用法不正确,这是mock patch最容易踩的坑之一,核心原因是patch的目标路径错了。
为什么不生效?
当你在w.py里执行from common.apis import MyAPI时,MyAPI已经被复制到当前模块(直接运行w.py时,模块名为__main__)的命名空间中。Worker类的__init__方法里调用的是当前模块的MyAPI引用,而不是common.apis原模块里的类。你patch的是原模块的MyAPI,但Worker根本没从那里取值,所以mock完全没作用。
两种修复方案
方案一:patch当前模块的MyAPI引用
直接修改patch的目标路径为当前模块的MyAPI,也就是__main__.MyAPI:
from common.apis import MyAPI class Worker: def __init__(self): companies = MyAPI.all() raise Exception(companies) if __name__ == "__main__": from mock import patch, Mock mock_api = Mock() mock_api.all.return_value = {'dummy': 'dummy'} # 修改patch路径为当前模块的MyAPI with patch('__main__.MyAPI', mock_api): Worker()
方案二:让Worker从原模块动态获取MyAPI
修改Worker的__init__方法,在内部延迟导入MyAPI,这样每次调用都会从common.apis取最新的引用,此时原patch路径就会生效:
class Worker: def __init__(self): # 延迟导入,确保每次都从原模块取MyAPI from common.apis import MyAPI companies = MyAPI.all() raise Exception(companies)
核心原则
mock patch的关键规则:patch对象被实际使用的命名空间,而非对象定义的命名空间。简单说,你的代码最后从哪个地方拿这个对象,就patch那个地方的引用。
内容的提问来源于stack exchange,提问作者user1187968
相关产品推荐
相关产品推荐

