unittest.mock patch装饰器全量pytest执行时未被调用的问题
问题排查:pytest全量测试时mock未生效的问题
现象说明
- 仅测试指定目录时,测试用例完全通过,patch方法正常生效:
docker compose -f docker-compose.local.yml run --rm django pytest ./project/app/ - 执行全量项目测试时,同一测试用例失败,mock方法未被触发:
docker compose -f docker-compose.local.yml run --rm django pytest # 或 docker compose -f docker-compose.local.yml run --rm django pytest project/ - 报错信息:
AssertionError: Expected 'generate_connect_token' to have been called once. Called 0 times.
相关文件路径
- Docker Compose文件:
~\src\docker-compose.local.yml - 测试用例文件:
~\src\project\app\tests\test_api_views.py
测试用例代码
@patch("project.app.pluggy_integration.utils.generate_connect_token", autospec=True) def test_get_token(self, mock_get_user_portfolio_data): mock_token = "ABCD" mock_get_user_portfolio_data.return_value = mock_token response = self.client.get(url_call) mock_get_user_portfolio_data.assert_called_once() assert response.status_code == status.HTTP_200_OK
排查方向
- 导入路径不匹配:全量测试时,被测试视图可能采用了相对导入(比如
from .utils import generate_connect_token)而非绝对导入,导致patch的目标路径和实际运行时加载的模块路径不一致,mock无法覆盖真实调用。可以检查视图文件中generate_connect_token的导入方式,调整patch路径为视图实际导入的模块路径。 - 模块重复导入问题:全量测试时,目标模块可能被多次导入,patch仅作用于第一次导入的模块实例,而实际运行时调用的是后续导入的实例。可以尝试在测试用例中打印模块的
__file__属性,确认测试场景下模块的加载路径是否一致。 - pytest配置差异:全量测试可能加载了根目录的
pytest.ini或conftest.py配置,其中的pythonpath等设置改变了模块解析路径,导致patch失效。对比局部测试和全量测试时的Python模块搜索路径(可通过python -c "import sys; print(sys.path)"查看)。 - Docker容器工作目录差异:检查Docker容器内的工作目录,全量测试时的工作路径是否与局部测试一致,这会影响模块的相对导入解析。可在容器内执行
pwd和python -c "import project.app.pluggy_integration.utils; print(project.app.pluggy_integration.utils.__file__)"确认模块实际位置。
内容的提问来源于stack exchange,提问作者Nadav
相关产品推荐
相关产品推荐

