Как замокировать функцию, определенную в модуле пакета?
У меня есть следующая структура файлов:
|-- dirBar
| |-- __init__.py
| |-- bar.py
|-- foo.py
`-- test.py
Содержимое bar.py
:
def returnBar():
return 'Bar'
Содержимое foo.py
:
from dirBar.bar import returnBar
def printFoo():
print(returnBar())
Содержимое test.py
:
from mock import Mock
from foo import printFoo
from dirBar import bar
bar.returnBar = Mock(return_value='Foo')
printFoo()
Когда я выполняю команду python test.py
, результат — Bar
.
Вопрос: как замокировать returnBar
, чтобы он возвращал Foo
, и в результате printFoo
выводил это значение?
Редактирование: без внесения изменений в любые файлы, кроме test.py
.
1 ответ(ов)
Чтобы замокировать функцию из модуля bar
, вам нужно сначала импортировать модуль bar
, а затем импортировать модуль foo
. Пример кода будет выглядеть так:
from mock import Mock
from dirBar import bar
bar.returnBar = Mock(return_value='Foo')
from foo import printFoo
printFoo()
При импорте returnBar
в файл foo.py
вы связываете значение модуля с переменной returnBar
. Эта переменная является локальной и попадает в замыкание функции printFoo()
, когда foo
импортируется. Значения в замыкании не могут быть изменены из внешнего кода. Поэтому при импорте foo
, returnBar
должен уже содержать новое значение (замокированную функцию).
ИЗМЕНЕНИЕ: Хотя предыдущее решение работает, оно не является устойчивым, так как зависит от порядка импортов, что не является идеальным. Альтернативным решением, которое пришло мне в голову после первого, является импорт модуля bar
в foo.py
, вместо того чтобы импортировать только функцию returnBar()
:
from dirBar import bar
def printFoo():
print(bar.returnBar())
Это сработает, потому что теперь функция returnBar()
вызывается напрямую из модуля bar
, а не из замыкания. Таким образом, если я обновлю модуль, новая функция будет извлечена.
Как клонировать список, чтобы он не изменялся неожиданно после присваивания?
Преобразование списка словарей в DataFrame pandas
Ошибка: "'dict' объект не имеет метода 'iteritems'"
Как явно освободить память в Python?
Выбор строки из pandas Series/DataFrame по целочисленному индексу