繁体   English   中英

如何导入和猴子补丁 Python 模块,该模块位于与测试不同的 package 中?

[英]How do I import and monkey patch a Python module that is in a different package from the tests?

我的源代码树如下所示:

.
├── 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 (自然)像这样import roku_lib lib.py

但是要让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/

这个单元测试失败了:

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保留在应用程序 package 中。 不过,如果这样可以解决我的问题,我可以将lib.py移动到单独的 package 中。

所以最后我的问题...

如何修复导入或猴子补丁代码(或两者)以便猴子补丁工作?

是否有可能(通过在缺少的地方添加额外的空__init__.py文件,也许?)在没有sys.path.append("app")的情况下让导入在test_lib.py中工作?

我将lib.py移动到libs目录中:

.
├── README.md
├── app
│   ├── __init__.py
│   └── flask_main.py
├── libs
│   ├── __init__.py
│   ├── lib_a.py
│   └── lib_b.py
├── run_endpoint_check_tests.sh
├── run_unit_tests.sh
└── tests
    ├── endpoint_checks.py
    ├── test_lib_a.py
    └── test_lib_b.py

(我将lib.py拆分为lib_a.pylib_b.pylib_b.py导入lib_a 。)

我在flask_main.pylib_b.pytest_lib_a.pylib_b.py中以相同的方式导入lib_a.pytest_lib_b.py

sys.path.append("..")
from libs import lib_a
from libs import lib_b

现在flask_main.py运行正常并且单元测试通过(猴子补丁断言没有失败)。

注意我删除run_flask.sh ,因为我现在必须以app目录作为 cwd 运行flask_main.py

另请注意,我仍然必须运行python -m pytest ——运行pytest会导致 ModuleNotFoundErrors。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM