AsyncMock records calls to an asynchronous collaborator separately from completed awaits.
Python AsyncMock: assert that a collaborator was awaited
Operation contract
The receipt handler awaits its injected writer before returning an accepted status. The test checks the awaited argument with assert_awaited_once_with. A second mock is called but never awaited; its call count increases while await_count remains zero. That difference catches a common bug where a coroutine object is constructed and discarded.
Failure and ownership boundary
A mock verifies interaction with a substitute, not database durability or network delivery. The injected writer is trusted here; real tests need failure and cancellation paths too. Python IsolatedAsyncioTestCase: own async setup and cleanup per test, Python unittest.mock: inject a collaborator failure before publication and Python asyncio.gather: a sibling can continue after the first failure show follow-up checks.
Working program
import asyncio
from unittest.mock import AsyncMock
async def accept_receipt(identifier, writer):
await writer(identifier)
return "accepted"
async def main():
writer = AsyncMock()
print(await accept_receipt("R41", writer))
writer.assert_awaited_once_with("R41")
print("awaited:", writer.await_count)
unused = AsyncMock()
pending = unused("R42")
print("called but not awaited:", unused.call_count, unused.await_count)
pending.close()
asyncio.run(main())Output
accepted
awaited: 1
called but not awaited: 1 0Costs and limits
The fixture has two mock calls and no external I/O. Mock bookkeeping adds local overhead; it is not a measurement of the real writer. Await assertions do not prove a side effect committed.
Common Mistakes
- assert_called_once_with does not prove an async function was awaited.
- Close an intentionally unawaited coroutine in a test to avoid a warning.
Connected lessons
Python IsolatedAsyncioTestCase: own async setup and cleanup per test, Python unittest.mock: inject a collaborator failure before publication, Python asyncio.gather: a sibling can continue after the first failure.
