Мое исходное дерево выглядит так:
.
├── README.md
├── app
│ ├── __init__.py
│ ├── flask_main.py
│ └── lib.py
├── run_endpoint_check_tests.sh
├── run_flask.sh
├── run_unit_tests.sh
└── tests
├── endpoint_checks.py
└── test_lib.py
flask_main.py
(естественно) импортирует lib.py
вот так: import roku_lib
Но чтобы получить test_lib.py
для импорта lib.py
, мне нужно сделать это:
sys.path.append("app")
from app import lib
И я запускаю модульные тесты, используя это (в run_unit_tests.sh
):
#!/bin/sh
python -m pytest
(я не смог запустить pytest
для работы, что, я думаю, имеет смысл после чтения https://docs.pytest.org/en/latest/goodpractices.html#tests -outside-application-code .)
Однако этот модульный тест не проходит:
def test_load_from_s3(mocker, monkeypatch):
x_mock = mocker.Mock()
return_mock = mocker.Mock()
x_mock.Object = mocker.Mock(return_value=return_mock)
monkeypatch.setattr(lib, 'get_x', lambda: x_mock)
y = lib.get_x()
x_mock.Object.assert_called_once()
...
Я думаю, что это не удается, потому что вызов lib.get_x () приводит к импорту его собственной (копии?) Библиотеки, не исправленной обезьяной.
Тот же тест работает, когда исходное дерево выглядит так:
.
├── README.md
├── __init__.py
├── lib.py
├── uses_lib.py
└── tests
├── __init__.py
├── test_uses_lib.py
└── test_lib.py
И sys.path.append("app")
и from app import lib
не нужны.
Но по историческим причинам я должен сохранить flask_main.py
в пакете приложения. Я мог бы переместить lib.py
в отдельный пакет, если это решит мою проблему.
Итак, наконец, мои вопросы ...
Как мне исправить импорт или код исправления обезьяны (или оба ) так что патч обезьяны работает?
Возможно ли (добавив лишние пустые __init__.py
файлы, где они отсутствуют, возможно?) заставить импорт работать в test_lib.py
без sys.path.append("app")
?