我继承了一些我必须测试的代码,但不幸的是,这段代码并没有考虑到可测试性(没有依赖注入,没有任何东西),所以我遇到了一些麻烦。
问题基本上是巨大的依赖树:当我导入模块时,我的代码将被测试(让我们称之为mymodule
),导入的模块,导入一些其他模块,这些模块执行一些导入好吧(自动甚至与数据库建立连接)。这很糟糕,但我可以忍受它使用酷mock
框架模拟每个模块。
但最糟糕的是,我要测试的类(让我们称之为MyClass
)继承自另一个与ORM相关的类......(让我们称之为ORMBase
),这完全破坏了代码的可测试性,因为我要测试的许多方法都使用来自此ORMBase
的一些方法。我无法直接模拟ORMBase
,因为class MyClass(ORMBase)
是在加载时执行的,而不是在运行时...
“幸运的是”我发现在加载之前拦截ORMBase的一种hackish方式,包括将mymodule.py
文件作为文本读取,识别导入并在sys.modules
中模拟它们。所以,我更改了ORMBase
类的mock.MagicMock
类,并且我可以执行测试。
我需要mymodule.py
文件的硬盘中的路径。当我试用hacky解决方案时,我使用了硬编码文件路径,但这不是一个长期解决方案。所以我试图找到.py文件的路径而不导入它。我看到similar questions建议使用模块pkgutil
和imp
,但事实是,它们不会阻止模块加载。
示例:
assert 'zc' not in sys.modules, 'pre'
loader = pkgutil.get_loader('package.subpackage.module')
assert 'ab' not in sys.modules, 'post'
会引发此异常:
assert 'ab' not in sys.modules, 'post'
AssertionError: post
所以我的下一个想法是自己手动走pythonpath,然后使用文件夹/文件,直到找到mymodule.py的路径,但我预见到这种方法存在一些问题。还有更好的主意吗?
感谢。