我是unittest
代码,其中包含一个执行本地导入的方法.
def function_under_test(): import unknown.dependency
(我没有在.py
文件顶部使用导入,因为调用该函数时它可能存在也可能不存在.)
unknown.dependency
以通常的方式进行模拟只有在某处可以找到它时才有效sys.path
.否则,调用patch
失败(它拒绝模拟它无法看到的东西):
with mock.patch('unknown.dependency'): function_under_test() >>> ImportError: No module named 'unknown'
文档建议我应该修补使用模块的命名空间 - 在这种情况下,function_under_test
.但是,当该命名空间是一个函数时,这不会削减它.调用patch
成功,但实际的import语句仍然引用原始的,不存在的unknown
模块,该模块无法找到.
with mock.patch('method_under_test.unknown'): print("fails") >>> ImportError: No module named 'unknown'
那么,如果模块本身不存在并且从函数导入,如何用模拟替换依赖模块呢?
简单的方法是将import语句移动到单独的函数中.
def get_dependency(): import unknown.dependency return unknown.dependency def function_under_test(): module = get_dependency() # use module
这样可以很容易地模拟出"辅助"功能.这样做的缺点是需要更改被测代码.它确实有效:
with mock.patch('get_dependency'): function_under_test()
如上所述在这里,你可以嘲笑的模块添加直奔sys.modules
这样Python才能找到它,无论它是存在于sys.path
与否.
with mock.patch.dict('sys.modules', unknown=mock.MagicMock()): function_under_test()