This rule raises an issue when a unittest.mock.Mock (or a mock created by patch / pytest-mock) is used with an assertion
attribute whose name closely resembles a real mock assertion method — for example a typo such as assert_called_wit instead of
assert_called_with. This rule only applies to method names that closely match a known assertion API.
Typical cases include typos on methods such as assert_called, assert_called_with, assert_called_once_with,
assert_any_call, assert_has_calls, and assert_not_called, on Mock, MagicMock, or
mocks returned by unittest.mock.patch / pytest-mock.
unittest.mock.Mock creates child attributes on demand. Any unknown name becomes another Mock, including misspelled
assertion methods.
Calling mock.assert_called_wit(…) therefore does not fail: it builds a new mock and returns it. The test keeps passing even though
the intended assertion never ran.
mock = Mock() service(mock) mock.assert_called_wit(1, 2) # typo: creates a child mock, does not assert
The call looks like an assertion, but it is only attribute access on a Mock.
mock = Mock() service(mock) mock.assert_called_with(1, 2)
Using a real assertion method fails the test when the mock was not called as expected.
This rule reports only when the attribute name is a near miss of a documented Mock assertion method (a small spelling difference), so
clearly unrelated assert_* names are not flagged. Review manually only if the code intentionally reads a nested mock attribute whose name
merely resembles an assertion helper (this is rare and usually a smell of its own).
Broken tests can pass silently. Regressions that the assertion was meant to catch go unnoticed, which weakens confidence in the suite and can let faulty behavior reach production.
Rename the attribute to the correct Mock assertion method so the test performs the check you intended. Do not change production code:
only the test assertion spelling should change, and the asserted call arguments should stay the same.
Optionally harden the mock with autospec (see {rule:python:S9137}) so future unknown attribute names raise instead of creating child mocks. That is a separate improvement; the required fix for this issue is correcting the assertion name.
A won’t-fix / accepted trade-off is not appropriate for a misspelled assertion: the test is not verifying what it claims. Mark as a false positive only if analysis mistook a non-assertion attribute access for a mock assertion API.
from unittest.mock import Mock
def test_process_calls_save():
saver = Mock()
process(saver, "item")
saver.save.assert_called_wit("item") # Noncompliant
from unittest.mock import Mock
def test_process_calls_save():
saver = Mock()
process(saver, "item")
saver.save.assert_called_with("item")
from unittest.mock import patch
def test_notify():
with patch("app.notify.send") as send:
notify_user("u1")
send.assert_called_once_wit("u1") # Noncompliant
from unittest.mock import patch
def test_notify():
with patch("app.notify.send") as send:
notify_user("u1")
send.assert_called_once_with("u1")
unittest.mock.MockMock.assert_called_with