如何获取模块文件的路径而不导入它

时间:2013-11-12 10:50:16

标签: python testing mocking tdd

我继承了一些我必须测试的代码,但不幸的是,这段代码并没有考虑到可测试性(没有依赖注入,没有任何东西),所以我遇到了一些麻烦。

场景

问题基本上是巨大的依赖树:当我导入模块时,我的代码将被测试(让我们称之为mymodule),导入的模块,导入一些其他模块,这些模块执行一些导入好吧(自动甚至与数据库建立连接)。这很糟糕,但我可以忍受它使用酷mock框架模拟每个模块。

但最糟糕的是,我要测试的类(让我们称之为MyClass)继承自另一个与ORM相关的类......(让我们称之为ORMBase),这完全破坏了代码的可测试性,因为我要测试的许多方法都使用来自此ORMBase的一些方法。我无法直接模拟ORMBase,因为class MyClass(ORMBase)是在加载时执行的,而不是在运行时...

hacky解决方案

“幸运的是”我发现在加载之前拦截ORMBase的一种hackish方式,包括将mymodule.py文件作为文本读取,识别导入并在sys.modules中模拟它们。所以,我更改了ORMBase类的mock.MagicMock类,并且我可以执行测试。

真正的问题

我需要mymodule.py文件的硬盘中的路径。当我试用hacky解决方案时,我使用了硬编码文件路径,但这不是一个长期解决方案。所以我试图找到.py文件的路径而不导入它。我看到similar questions建议使用模块pkgutilimp,但事实是,它们不会阻止模块加载。

示例:

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的路径,但我预见到这种方法存在一些问题。还有更好的主意吗?

感谢。

0 个答案:

没有答案