Как замокировать функцию, определенную в модуле пакета?
У меня есть следующая структура файлов:
|-- 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, а не из замыкания. Таким образом, если я обновлю модуль, новая функция будет извлечена.
Python - объект MagicMock не может быть использован в выражении 'await'
Как изменить порядок столбцов в DataFrame?
'pip' не распознан как командa внутреннего или внешнего формата
Почему statistics.mean() работает так медленно?
Есть ли разница между поднятием экземпляра класса Exception и самого класса Exception?