no-test-method-grafting
Avoid assigning replacement implementations directly onto resolved methods in tests.
Why
Grafting a function onto a collaborator or mock hides the boundary's callable contract and bypasses the mock's call and await records. An injected fake makes behavior explicit; configuring an existing contract-aware mock preserves its observation API. Scoped patches also restore real objects reliably.
Fix
Inject a concrete fake or configure the existing autospecced mock method's return_value or side_effect. Preserve the real method's synchronous or asynchronous contract, including synchronous awaitable returns. Explain other intentional runtime interception with an exact-code local suppression.
Examples
from unittest.mock import Mock
class Sender: def send(self, text: str) -> None: pass
def test_delivery(): sender = Mock(spec=Sender) messages = []
def record(text: str) -> None: messages.append(text)
sender.send = recordfrom unittest.mock import create_autospec
class Sender: def send(self, text: str) -> None: pass
def test_delivery(): sender = create_autospec(Sender, instance=True, spec_set=True) messages = [] sender.send.side_effect = messages.append sender.send("hello") sender.send.assert_called_once_with("hello")