0

Как замокировать функцию, определенную в модуле пакета?

6

У меня есть следующая структура файлов:

|-- 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 ответ(ов)

0

Чтобы замокировать функцию из модуля 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, а не из замыкания. Таким образом, если я обновлю модуль, новая функция будет извлечена.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь