python
runtime_error
ai_generated
true
AssertionError: 期望 'send_email' 被调用一次。实际调用 0 次。
AssertionError: Expected 'send_email' to be called once. Called 0 times.
ID: python/mock-patch-wrong-target
80%修复率
89%置信度
0证据数
2024-01-19首次发现
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 3.11 | active | — | — | — |
| 3.12 | active | — | — | — |
根因分析
unittest.mock.patch 打补丁的对象是函数定义所在的模块,但被测代码通过 from ... import 把该函数导入了自己的命名空间。补丁替换的是原始符号,而非已导入的引用。
English
unittest.mock.patch targeted the module where the function is defined, but the code under test imported it by name into its own namespace. The patch replaces the original symbol, not the already-imported reference.
解决方案
-
94% 成功率
# app/service.py: from app.mail import send_email def notify(user): send_email(user.email) # test_service.py from unittest.mock import patch @patch('app.service.send_email') def test_notify(mock_send): notify(user) mock_send.assert_called_once() -
92% 成功率
def test_notify(mocker): m = mocker.patch('app.service.send_email') notify(user) m.assert_called_once_with('[email protected]')
无效尝试
常见但无效的做法:
-
80% 失败
The real function is being called, not the mock. Changing call counts doesn't make the patch take effect.
-
70% 失败
autospec validates the signature but still patches the wrong namespace; the code under test still holds the original reference.