Always Mock With Autospec True
Your mocks accept methods that do not exist. A plain Mock (or MagicMock) is infinitely agreeable: call mock.fetch_userz(), mock.send(1, 2, 3, 4, 5), or any misspelled, renamed, or hallucinated method, and it happily returns another mock. The test goes green. In an AI-assisted codebase — where an agent may rename a method, guess a parameter, or invent an API — that agreeableness turns your test suite into a rubber stamp.
Why a plain Mock lies to you
Mock auto-creates attributes on access. That is the feature that makes mocking convenient, and it is also the failure mode: nothing ties the mock to the real object's interface. Concretely, two things go unchecked:
- Nonexistent attributes. Rename
Client.get_usertoClient.fetch_userin production code. A test that patchesClientwith a plain mock and callsclient.get_user()still passes — the mock inventsget_useron the spot. - Wrong signatures. Add a required argument to a real function. Tests calling the mocked version with the old arity still pass, because a plain mock accepts any call.
Both are exactly the mistakes AI coding assistants make most often: plausible-but-wrong method names and slightly-off call signatures.
The fix: autospec=True
Pass autospec=True to patch() and the mock is built from the real object's spec — recursively. Per the Python docs: "All attributes of the mock will also have the spec of the corresponding attribute of the object being replaced," and mocked functions "will have their arguments checked and will raise a TypeError if they are called with the wrong signature."
from unittest.mock import patch
# Rubber stamp: passes even if get_user() was renamed
with patch("app.client.Client") as mock_client:
mock_client.return_value.get_userz() # green, silently wrong
# Reality check: fails the moment the API drifts
with patch("app.client.Client", autospec=True) as mock_client:
mock_client.return_value.get_userz() # AttributeError
mock_client.return_value.get_user("a", "b") # TypeError if the real
# signature is get_user(id)
Accessing an attribute the real object doesn't have raises AttributeError; calling with the wrong arguments raises TypeError — the same way production code would fail. Your tests now catch AI misuse of an API instead of quietly hiding it.
Rules of thumb
| Situation | Use |
|---|---|
patch() a class, function, or module attribute | patch(target, autospec=True) — the default habit |
| Build a spec'd mock by hand (no patching) | create_autospec(RealThing) |
| Also forbid setting attributes that don't exist | spec_set=True (stricter variant of spec) |
| Mock should act like an instance, not the class | create_autospec(RealThing, instance=True) |
| Legacy plain mocks you can't rewrite yet | at minimum patch(target, spec=True) |
spec=True checks attribute access; spec_set=True additionally raises AttributeError when a test assigns an attribute the real object lacks — which catches typos in your test setup itself.
Power-user notes
- Signature-aware assertions. A spec'd mock introspects the real signature, so
assert_called_with()matches positional and keyword forms of the same call —mock.get_user(1)andmock.get_user(id=1)compare equal. Plain mocks treat them as different calls. - Classes spec their instances. With
autospec=Trueon a class, the mock'sreturn_value(the "instance") carries the same spec, so the whole chain is checked. - Known limitation:
__init__-created attributes. Autospec introspects the class, so attributes created only inside__init__(e.g.self.session = ...) are invisible to it and will raiseAttributeErrorin tests. Set them explicitly on the mock, or expose them at class level. - Cost. Autospec builds the spec recursively via introspection, so it is slower than a bare
Mock— negligible for most suites, worth knowing for very hot fixtures. - Make it the default in review. A cheap, high-yield lint for AI-generated tests: flag any
patch(withoutautospec=True(or an explicitspec). It is one argument, and it converts "the tests pass" back into evidence.
Resources
- Autospeccing — unittest.mock docs
- patch() — unittest.mock docs
- create_autospec() — unittest.mock docs
- spec and spec_set — Mock class reference
- unittest.mock — getting started examples
Building an AI feature? Yeda AI designs, audits, and ships production LLM systems.