单元测试中使用@patch装饰器Mock send_request()函数失败问题排查
问题原因:Patch路径错误
unittest.mock的@patch装饰器需要作用于被测试代码实际使用目标函数的位置,而非函数的定义位置。你的场景中:
send_request定义在logic.py,但ui.py通过from logic import send_request将其导入到自身模块的命名空间UserInterface.send_click调用的是ui模块本地的send_request引用,而非直接调用logic.send_request
测试中使用@patch("ui.send_request"),但该路径在测试上下文里未正确指向ui模块内的send_request引用(比如测试文件层级导致模块路径解析错误),最终导致mock没有替换掉实际被调用的函数。
解决方案
方案1:使用绝对模块路径Patch
假设你的项目结构如下:
my_project/ ├── logic.py ├── ui.py └── tests/ └── test_ui.py
ui模块的绝对路径为my_project.ui,patch时使用该绝对路径:
from ..ui import UserInterface from unittest.mock import patch, Mock @patch("my_project.ui.send_request") # 替换为你的实际项目包名+ui模块路径 def test_send_request(mock_send_request, qtbot): ui = UserInterface() ui.get_request_data = Mock() data = QByteArray(data_str_create.encode("utf-8")) action_method, url, data = ACTIONS_METHODS.POST, QUrl("http://example.com/api"), data ui.get_request_data.return_value = action_method, url, data ui.send_click() mock_send_request.assert_called_once()
方案2:直接Patch导入的ui模块属性
先在测试文件中导入ui模块,再用patch.object直接patch该模块的send_request属性,这种方式能避免路径解析问题,更可靠:
from .. import ui # 直接导入ui模块 from ..ui import UserInterface from unittest.mock import patch, Mock @patch.object(ui, "send_request") def test_send_request(mock_send_request, qtbot): ui_instance = UserInterface() ui_instance.get_request_data = Mock() data = QByteArray(data_str_create.encode("utf-8")) action_method, url, data = ACTIONS_METHODS.POST, QUrl("http://example.com/api"), data ui_instance.get_request_data.return_value = action_method, url, data ui_instance.send_click() mock_send_request.assert_called_once()
验证修改
修改后运行测试,输出中的send_request mock会显示mock对象信息(如<MagicMock name='send_request' id='...'>),且不会再打印send request,断言也会正常通过。
内容的提问来源于stack exchange,提问作者user3565923
相关产品推荐
相关产品推荐

