Я начинаю использовать библиотеку Python Mock для моего тестирования. Я хочу смоделировать модуль, который импортируется в пространство имен тестируемого модуля, фактически не импортируя его или не требуя, чтобы он существовал первым (т.е. Выдавая ImportError).
Предположим, существует следующий код:
foo.py
import helpers
def foo_func():
return helpers.helper_func()
Цель состоит в том, чтобы протестировать foo_func(), когда 'helpers.py' нигде не существует, и если он существует, действовать так, как будто его нет.
Сначала попробуйте, используя супер классный декоратор @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
Это работает, если модуль "помощников" можно импортировать. Если он не существует, я получаю 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
Опять же, это не работает, если "помощники" отсутствуют... и, если оно существует, утверждение не выполняется. Не совсем уверен, почему это происходит.
Третья попытка, текущее решение:
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() == sentinel.foobar
Этот тест проходит независимо от того, существует ли "helpers.py".
Это лучший способ для достижения этой цели? Предоставляет ли библиотека-издевательство альтернативу этому? Какие еще способы я могу сделать это?