使用python unittest.mock如何mock自有库中实例化的外部库对象
报错原因
unittest.patch的核心替换逻辑是:在目标对象被使用的命名空间下替换引用,而非直接替换源定义位置的对象,你当前的写法存在两个问题:
Client是service/my_service.py模块顶层导入的外部对象,不是Service类的类属性,去Service类下查找Client属性自然会抛出属性不存在的错误。- 路径指向错误:
Service类初始化时调用的Client(token),查找Client的作用域是service.my_service模块的全局命名空间,和my_project模块下导入的Service引用没有从属关系。
正确mock方案
直接替换service.my_service模块下导入的Client引用即可,这种写法只会替换Service类用到的Client对象,不会影响其他模块对真实Client的调用,测试隔离性更好:
from unittest.mock import patch from my_project import main @patch('service.my_service.Client') def test_main(client_mock): # 按需配置mock对象的行为 mock_client_instance = client_mock.return_value # 例:配置客户端方法的返回值 # mock_client_instance.query.return_value = {"status": "success"} main() # 验证Client初始化参数符合预期 client_mock.assert_called_once_with("123456") # 按需验证后续服务对客户端的调用逻辑 # mock_client_instance.query.assert_called_once()
这种写法会在Service初始化时,自动将Mock生成的客户端实例赋值给self.__client私有属性,后续Service内部对客户端的所有调用都会被Mock捕获,完全满足隔离外部依赖测试main()逻辑的需求。
注意:不要直接patch
external_library.Client,这种写法会全局替换外部库的Client类,可能污染其他测试用例的执行环境,导致测试结果不可靠。
内容的提问来源于stack exchange,提问作者user19451321
相关产品推荐
相关产品推荐

