如何二次导入Python模块以测试导入时的校验逻辑?
问题原因
- 导入语法错误:
from numbers.py import DICT_NUMBER写法错误,Python导入模块不需要加.py后缀,该写法会直接触发模块找不到错误,自然提示DICT_NUMBER未定义。 - Python模块导入有全局缓存:首次导入完成后模块会被存入
sys.modules字典,后续所有导入操作都会直接返回缓存的模块对象,不会重新执行模块顶层代码,你的二次导入根本不会触发校验逻辑。 - 校验逻辑只在模块初始化阶段执行:你修改已导入模块的
DICT_NUMBER属性时,顶层的for循环校验已经执行完毕,修改不会再触发校验。
解决方案
核心思路是每次测试前清除模块缓存,保证每次导入都会重新执行顶层校验逻辑,需要测试异常场景时可通过mock替换模块初始化时的DICT_NUMBER值。
示例测试代码(基于unittest框架)
import sys import unittest from unittest.mock import patch # 提前引入你代码中的Number基类和A类,根据你的实际代码路径调整 from your_module import Number, A class TestNumbersModuleImport(unittest.TestCase): def setUp(self): # 每次测试前清除numbers模块的缓存,保证每次都是全新导入 if 'numbers' in sys.modules: del sys.modules['numbers'] def test_normal_import_success(self): # 测试正常配置下导入无异常 import numbers self.assertEqual(len(numbers.DICT_NUMBER), 5) def test_invalid_class_import_raise_error(self): # 导入前patch替换模块内的DICT_NUMBER,插入非法类A with patch('numbers.DICT_NUMBER', {'A': A}): # 预期导入时抛出异常 with self.assertRaises(Exception) as ctx: import numbers self.assertIn('is not extending Number', str(ctx.exception)) if __name__ == '__main__': unittest.main()
额外说明
如果用pytest框架,逻辑完全一致,只需要把测试用例改成pytest的写法,用pytest自带的monkeypatch或者unittest.mock都可以实现。
内容的提问来源于stack exchange,提问作者Leonardo Furtado
相关产品推荐
相关产品推荐

