我开始使用python 模拟库进行测试.我想模拟一个在被测模块的命名空间中导入的模块,而不是实际导入它或要求它首先存在(即抛出一个ImportError).
假设存在以下代码:
foo.py
import helpers
def foo_func():
return helpers.helper_func()
Run Code Online (Sandbox Code Playgroud)
目标是在'helpers.py'不存在于任何地方时测试foo_func(),如果确实存在,则表现为不行.
首先尝试使用超酷的@patch装饰器:
from mock import patch, sentinel
import foo
@patch("foo.helpers")
def foo_test(mock):
mock.helper_func.return_value = sentinel.foobar
assert foo.foo_func() == sentinel.foobar
Run Code Online (Sandbox Code Playgroud)
如果可以导入"帮助程序"模块,则此方法有效.如果它不存在,我会得到一个ImportError.
下一次尝试补丁,没有装饰者:
from mock import patch, sentinel, Mock
import foo
helpers_mock = patch("foo.helpers")
helpers_mock.start()
def foo_test():
helpers_mock.helper_func = Mock('helper_func')
helpers_mock.helper_func.return_value = sentinel.foobar
assert foo.foo_func() == sentinel.foobar
Run Code Online (Sandbox Code Playgroud)
同样,如果缺少"助手",这不起作用......如果存在,则断言失败.不确定为什么会这样.
第三次尝试,当前解决方案
import sys
helpers_mock = Mock(name="helpers_mock", spec=['helper_func'])
helpers_mock.__name__ = 'helpers'
sys.modules['helpers'] = helpers_mock
import foo
def foo_test():
helpers_mock.helper_func.return_value = sentinel.foobar
assert foo.foo_func() == …Run Code Online (Sandbox Code Playgroud)