python
runtime_error
ai_generated
true
AssertionError: Expected 'send_email' to be called once. Called 0 times.
ID: python/mock-patch-wrong-target
80%Fix Rate
89%Confidence
0Evidence
2024-01-19First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 3.11 | active | — | — | — |
| 3.12 | active | — | — | — |
Root Cause
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.
generic中文
unittest.mock.patch 打补丁的对象是函数定义所在的模块,但被测代码通过 from ... import 把该函数导入了自己的命名空间。补丁替换的是原始符号,而非已导入的引用。
Workarounds
-
94% success
# 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% success
def test_notify(mocker): m = mocker.patch('app.service.send_email') notify(user) m.assert_called_once_with('[email protected]')
Dead Ends
Common approaches that don't work:
-
80% fail
The real function is being called, not the mock. Changing call counts doesn't make the patch take effect.
-
70% fail
autospec validates the signature but still patches the wrong namespace; the code under test still holds the original reference.