我继承了一些我必须测试的代码,但不幸的是,这段代码没有考虑到可测试性(没有依赖注入,什么都没有),所以我遇到了一些麻烦。
场景
问题基本上是巨大的依赖树:当我导入要测试的代码所在的模块时(让我们称之为mymodule
),导入的模块,导入一些其他模块并且这些模块也进行一些导入(甚至自动进行一些连接到数据库)。这很糟糕,但我可以忍受它用很酷的方式嘲笑每个模块mock
框架模拟每个模块。
但最糟糕的是,我要测试的类(我们称之为MyClass
)继承自另一个与 ORM 相关的类......(我们称之为ORMBase
),这完全破坏了代码的可测试性,因为我想测试的许多方法使用一些由此而来的方法ORMBase
。而且我不能直接模拟,ORMBase
因为它class MyClass(ORMBase)
是在加载时执行的,而不是在运行时......
骇人听闻的解决方案
“幸运的是”我找到了一种在加载 ORMBase 之前拦截它的黑客方法,其中包括将mymodule.py
文件作为文本读取,识别导入并在sys.modules
. 所以,我改变了ORMBase
班级mock.MagicMock
班级,瞧,我可以进行测试了。
真正的问题
我需要文件硬盘驱动器中的路径mymodule.py
。当我测试 hacky 解决方案时,我使用了硬编码的文件路径,但这不是一个长期的解决方案。所以我试图找到一个 .py 文件的路径而不导入它。我见过类似的问题,建议使用模块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的路径,但我预见到这种方法会出现一些问题。有更好的主意吗?
谢谢。