Python单元测试如何mock其他文件中的import导入语句
解决方案
直接使用Python标准库unittest.mock的patch能力,在实例化类A时临时替换class_file模块命名空间下的lib1、lib2为mock对象,不需要重写__init__方法,完全复用原有实例化逻辑。
完整实现代码
# test.py from unittest.mock import MagicMock, patch from class_file import A def get_mocked_a(condition: bool = True): # patch目标必须是class_file模块下绑定的lib1、lib2变量,而非原始依赖库本身 with patch("class_file.lib1") as mock_lib1, patch("class_file.lib2") as mock_lib2: # 按需配置mock对象的接口、返回值,和真实库行为保持一致即可 # 示例配置: mock_lib1.query.return_value = "mocked result from lib1" mock_lib2.query.return_value = "mocked result from lib2" # 完全走原有__init__逻辑实例化 a_instance = A(condition=condition) # 退出with块后patch自动还原模块引用,不会污染其他测试逻辑 return a_instance def test(): # 获取condition=True的实例,attr为mock版lib1 a1 = get_mocked_a(condition=True) print(a1.attr.query()) # 输出 mocked result from lib1 # 获取condition=False的实例,attr为mock版lib2 a2 = get_mocked_a(condition=False) print(a2.attr.query()) # 输出 mocked result from lib2
关键注意事项
- patch路径必须写
class_file.lib1/class_file.lib2:import lib1执行后,lib1是绑定在class_file模块全局命名空间的变量,类A的__init__方法读取的就是这个命名空间下的值,直接patch原始lib1路径不会生效。 - 退出
with代码块后,class_file模块的lib1/lib2引用会自动恢复为真实导入的对象,不会影响其他测试用例的运行。 - 实例化完成后,实例的
self.attr已经持有mock对象的引用,不受后续patch还原的影响,可正常调用mock配置的所有方法、属性。 - 如果原代码里导入的库名是笔误的
lib22,只需要把对应patch路径改成class_file.lib22即可,和文件中import语句后的变量名保持一致。 - 所有mock公共配置都可以封装在
get_mocked_a函数内部,测试用例只需要传入condition参数就能拿到配置完成的实例,满足测试代码简洁性要求。
内容的提问来源于stack exchange,提问作者Federico Taschin
相关产品推荐
相关产品推荐

