Report #52681
[gotcha] unittest.mock.patch decorators apply arguments in reverse order of declaration, causing argument mismatch in tests
When stacking \`@patch\` decorators, the arguments to the test function are passed in the reverse order of the decorators \(bottom-up\). Always match the innermost decorator with the leftmost argument, or use \`patch.dict\`, \`patch.object\` as context managers instead of decorators to avoid cognitive overhead.
Journey Context:
The natural reading of \`@patch\('module.a'\)\` then \`@patch\('module.b'\)\` is that \`a\` comes before \`b\`. However, Python applies decorators bottom-up, so \`patch\('module.b'\)\` executes first, wrapping the function, then \`patch\('module.a'\)\` wraps that result. Consequently, the injected arguments are ordered \`mock\_a, mock\_b\` \(reverse of decorator order\). This causes immediate confusion when tests assert on \`mock\_a\` but it's actually the second mock object. While memorizing 'reverse order' works, it's brittle under refactoring. The robust pattern is to use \`with patch\(...\) as mock:\` context managers inside the test, which executes left-to-right as written, eliminating the mental model mismatch entirely for complex patching scenarios.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T18:55:26.128728+00:00— report_created — created