@patch, похоже, не ведет себя так же, как в версиях 2.7 и 3.6.
Вот моя структура проекта:
project/
foo.py
bar.py
lol.py
tests/
test_project.py
foo.py:
class Foo:
pass
bar.py (импортирует Foo):
from project.foo import Foo
class Bar:
def __init__(self):
f = Foo()
lol.py (импортирует Bar):
from bar import Bar
class Lol:
def __init__(self):
b = Bar()
Поскольку bar.py импортирует Foo с помощью from project.foo import Foo, я исправляю bar.Foo (согласно документации где патчить):
test_bar.py:
from project import lol
from project import bar
@patch('bar.Foo') # Works in 3.6, fails with 2.7
def test_lol(mock_Foo):
l = lol.Lol()
mock_Foo.assert_called()
Эта установка работает правильно в Python 3.6, но не работает в 2.7 (Foo не исправляется).
Однако, если я переключу свою настройку на:
test_bar.py:
from project import lol
# from project import bar # No need to import bar anymore
@patch('project.bar.Foo') # Works in 2.7, fails with 3.6
def test_lol(mock_Foo):
l = lol.Lol()
mock_Foo.assert_called()
Он работает в 2.7, но не работает в 3.6.
Каков рекомендуемый способ использования @patch для обеспечения согласованности результатов между версиями Python?
Примечание. Эта проблема появляется только при тестировании lol.py. Если я вызываю bar.py из модульного теста, я получаю стабильные результаты, используя вторую установку @patch('cookie_test.bar.Foo'), и она работает как в 2.7, так и в 3.6.






Я не могу воспроизвести разницу, используя 2.7 и 3.6 при добавлении файлов __init__.py в ваш каталог project и изменении импорта Bar в lol.py:
from project.bar import Bar
В любом случае вам не нужно импортировать bar в свой тест - mock позаботится о поиске bar, проанализировав строку, переданную декоратору mock.
Я подозреваю, что ошибка, которую вы видите, связана с тем, что Python 3 использует абсолютный импорт (https://www.python.org/dev/peps/pep-0328/)