我正在编写一个测试套件,而我正在测试的代码过度使用延迟的模块导入。所以有可能对同一个方法有 5 个不同的输入,这最终可能会导入 5 个额外的模块。我想做的是设置测试,以便我可以断言使用一个输入运行该方法会导致一个导入,而不会导致其他 4 个。
我有一些关于如何开始的想法,但到目前为止还没有一个成功的。我已经有一个自定义导入器,我可以将日志记录代码放在导入器中。但这不起作用,因为 import 语句只运行一次。无论模块之前是否已导入,我都需要执行日志语句。只是运行del sys.modules['modname']
也不起作用,因为它在测试代码中运行,并且我无法在正在测试的代码中重新加载模块。
我尝试的下一件事是子类dict
化来进行监控,并用这个子类替换 sys.modules。这个子类有一个重新实现的__getitem__
方法,但是调用import module
似乎不会触发__getitem__
子类中的调用。我也不能直接分配给sys.modules.__getitem__
,因为它是只读的。
我想要做的甚至可能吗?
更新
nneonneo 的答案似乎仅在 的实现与logImports()
使用它的模块位于同一模块中时才有效。如果我创建一个包含此功能的基本测试类,它就会出现问题。首先是它找不到 just __import__
,错误如下:
# old_import = __import__
# UnboundLocalError: local variable '__import__' referenced before assignment
当我将其更改为 时__builtin__.__import__
,出现另一个错误:
我的单元测试.py:
import unittest
class TestCase(unittest.TestCase):
def logImports(self):
old_import = __builtins__.__import__
def __import__(*args, **kwargs):
print args, kwargs
return old_import(*args, **kwargs)
__builtins__.__import__ = __import__
测试.py:
import myunittest
import unittest
class RealTest(myunittest.TestCase):
def setUp(self):
self.logImports()
def testSomething(self):
import unittest
self.assertTrue(True)
unittest.main()
# old_import = __builtins__.__import__
# AttributeError: 'dict' object has no attribute '__import__'