[英]How do I import and monkey patch a Python module that is in a different package from the tests?
My source tree looks like this:我的源代码树如下所示:
.
├── 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
(naturally) imports lib.py
like this: import roku_lib
flask_main.py
(自然)像这样import roku_lib
lib.py
But to get test_lib.py
to import lib.py
, I need to do this:但是要让
test_lib.py
导入lib.py
,我需要这样做:
sys.path.append("app")
from app import lib
And I run the unit tests using this (in run_unit_tests.sh
):我使用它运行单元测试(在
run_unit_tests.sh
中):
#!/bin/sh
python -m pytest
(I haven't been able to get running pytest
to work, which I guess makes sense after reading https://docs.pytest.org/en/latest/goodpractices.html#tests-outside-application-code .) (我一直无法运行
pytest
工作,我认为在阅读https://docs.pytest.org/en/
This unit test fails though:这个单元测试失败了:
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()
...
I think it fails because calling lib.get_x() results in it importing it's own (copy of?) lib that is not monkey patched.我认为它失败了,因为调用 lib.get_x() 会导致它导入它自己的(副本?)没有猴子补丁的库。
The same test works when the source tree looks like this:当源代码树如下所示时,相同的测试工作:
.
├── README.md
├── __init__.py
├── lib.py
├── uses_lib.py
└── tests
├── __init__.py
├── test_uses_lib.py
└── test_lib.py
And sys.path.append("app")
& from app import lib
are unnecessary.并且
sys.path.append("app")
& from app import lib
是不必要的。
But for historical reasons, I must keep flask_main.py
in the app package.但由于历史原因,我必须将
flask_main.py
保留在应用程序 package 中。 I could move lib.py
into a separate package though, if that solves my problem.不过,如果这样可以解决我的问题,我可以将
lib.py
移动到单独的 package 中。
So finally my questions...所以最后我的问题...
How do I fix the imports or monkey patching code (or both) so the monkey patch works?如何修复导入或猴子补丁代码(或两者)以便猴子补丁工作?
Is it possible (by adding extra empty __init__.py
files where missing, perhaps?) to get the import to work in test_lib.py
without sys.path.append("app")
?是否有可能(通过在缺少的地方添加额外的空
__init__.py
文件,也许?)在没有sys.path.append("app")
的情况下让导入在test_lib.py
中工作?
I moved lib.py
into a libs
directory:我将
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
(And I split lib.py
into lib_a.py
and lib_b.py
. lib_b.py
imports lib_a
.) (我将
lib.py
拆分为lib_a.py
和lib_b.py
。 lib_b.py
导入lib_a
。)
And I import lib_a.py
and lib_b.py
the same way in flask_main.py
, lib_b.py
, and test_lib_a.py
& test_lib_b.py
:我在
flask_main.py
、 lib_b.py
和test_lib_a.py
和lib_b.py
中以相同的方式导入lib_a.py
和test_lib_b.py
:
sys.path.append("..")
from libs import lib_a
from libs import lib_b
Now flask_main.py
runs properly and the unit tests pass (with the monkey patch assertions not failing).现在
flask_main.py
运行正常并且单元测试通过(猴子补丁断言没有失败)。
Note I deleted run_flask.sh
since I now have to run flask_main.py
with the app
directory as the cwd.注意我删除
run_flask.sh
,因为我现在必须以app
目录作为 cwd 运行flask_main.py
。
Note also I still have to run python -m pytest
——running pytest
leads to ModuleNotFoundErrors.另请注意,我仍然必须运行
python -m pytest
——运行pytest
会导致 ModuleNotFoundErrors。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.