Skip to content

mock-without-spec

Unrestricted mock permits attributes outside the collaborator contract.

Why

A mock without a spec permits removed or misspelled attributes; a callable mock without autospec may also accept stale call shapes.

Fix

Use spec_set=RealType or a concrete fake for collaborators, autospec=True for patched callables, and create_autospec when direct-call signatures matter. Use object() or mock.sentinel for identity markers.

Examples

Before — flagged Mock accepts any attribute
tests/test_service.py
from unittest.mock import Mock
def test_service():
client = Mock()
client.send() # A typo or removed method still passes.
After — preferred Autospecced mock follows attributes and signatures
tests/test_service.py
from unittest.mock import create_autospec
def test_service():
client = create_autospec(Client, instance=True, spec_set=True)
client.send()
Before — flagged Patch generates an unrestricted replacement
tests/test_service.py
from unittest.mock import patch
def test_service():
with patch("app.client.Client.send") as send:
run_service()
send.assert_called_once()
After — preferred Patch preserves the callable contract
tests/test_service.py
from unittest.mock import patch
def test_service():
with patch("app.client.Client.send", autospec=True) as send:
run_service()
send.assert_called_once()