Batu Lab NotesPractical developer guides

Verify a mock call sequence without forbidding extra calls accidentally

By Batu ยท English technical notes

Also published in our primary archive.

assert_has_calls verifies that requested calls occur in the requested sequence, but it does not by itself forbid calls before or after that sequence. If a test needs an exact interaction history, compare mock_calls with the complete expected list instead.

The fixture records four method calls: a leading setup action, the two calls the test cares about, and a trailing cleanup action. assert_has_calls accepts [call.open("config"), call.write("enabled=true")] because those calls are adjacent and ordered. The fixture then deliberately checks that the full history is *not* equal to that two-call list. Its output makes the distinction concrete: sequence inclusion is true while exact history is false, and four calls were recorded.

This is useful when choosing the assertion to match the contract. A sequence assertion permits unrelated setup and cleanup, which can make a focused test less brittle. An equality assertion detects every additional, missing, or reordered recorded call. It can be too strict when the implementation is allowed to emit harmless surrounding interactions. mock_calls includes calls on the mock and its child methods, so choose the appropriate mock level before comparing histories.

The documented default for assert_has_calls requires sequential calls and permits extra calls before or after them. Mock is available in Python 3.3 and assert_has_calls is part of its standard API.

See the Python Mock.assert_has_calls documentation.

AI-assistance disclosure: AI helped draft this synthetic example and explanation.

from unittest.mock import Mock, call


client = Mock()
client.prepare()
client.open("config")
client.write("enabled=true")
client.close()

required_sequence = [call.open("config"), call.write("enabled=true")]
client.assert_has_calls(required_sequence)

exact_history = client.mock_calls == required_sequence
assert exact_history is False
assert client.mock_calls == [
    call.prepare(),
    call.open("config"),
    call.write("enabled=true"),
    call.close(),
]
print(f"sequence_included=True exact_history={exact_history} calls={len(client.mock_calls)}")
sequence_included=True exact_history=False calls=4