单元测试失败:同目录脚本类继承引发ModuleNotFoundError
问题排查与解决方案
错误原因
你当前的补丁只向sys.modules中添加了script1.A,但script2.py中的导入语句from script1 import A会先尝试加载整个script1模块,而这个模块并未在sys.modules中注册,因此依然会抛出ModuleNotFoundError。Python的模块导入逻辑是先找顶层模块,再从中获取指定类/对象,单独注册子模块或类无法替代顶层模块的存在。
可行解决方案
方案1:正确Mock整个script1模块
修改测试类的setUpClass方法,先Mock出完整的script1模块,再将其注册到sys.modules中:
from unittest import TestCase, mock from src.steps.project.script1 import A class TestB(TestCase): @classmethod def setUpClass(cls): # 创建Mock的script1模块对象 mock_script1 = mock.Mock() # 将实际的A类绑定到Mock模块上(也可以用mock.Mock()替代真实类) mock_script1.A = A # 注册整个script1模块到sys.modules cls.module_patcher = mock.patch.dict("sys.modules", {"script1": mock_script1}) cls.module_patcher.start() @classmethod def tearDownClass(cls): # 停止补丁 cls.module_patcher.stop() def setUp(self): from src.steps.project.script2 import B self.b_instance = B() def test_get_name(self): # 示例测试用例 self.b_instance.name = "test" self.b_instance.get_name()
方案2:将目标目录添加到Python搜索路径
直接把script1和script2所在的目录加入sys.path,让Python能正常找到该模块,无需Mock:
from unittest import TestCase import sys from pathlib import Path class TestB(TestCase): @classmethod def setUpClass(cls): # 计算script1所在的目录路径(基于测试文件的相对位置) script_dir = Path(__file__).resolve().parent.parent.parent.parent / "src" / "steps" / "project" sys.path.append(str(script_dir)) def setUp(self): from src.steps.project.script2 import B self.b_instance = B()
方案3:修改script2.py的导入语句(可选)
如果允许调整业务代码,可以将script2.py中的导入改为相对导入,同时确保项目根目录src被加入sys.path:
# script2.py中修改导入 from .script1 import A
注:此方案需要保证在AWS运行时,脚本的执行环境支持相对导入(直接运行单个脚本时可能需要额外处理,建议结合方案2一起使用)。
内容的提问来源于stack exchange,提问作者Amy
相关产品推荐
相关产品推荐

