Quick Start¶
This guide walks through a complete bigfoot test from setup to teardown and shows what each of the three error types looks like when violated.
Step 1: Import bigfoot¶
bigfoot registers an autouse pytest fixture behind the scenes. Every test automatically gets a fresh StrictVerifier. No fixture injection or conftest.py changes are needed.
Step 2: Create a mock¶
bigfoot.mock("EmailService") returns a MockProxy named "EmailService". The name is used in error messages and assert_interaction() calls. Calling bigfoot.mock() with the same name twice within a test returns the same proxy.
Step 3: Configure return values¶
Attribute access on a MockProxy returns a MethodProxy. .returns(True) appends a return-value entry to the method's FIFO queue. The first call to email.send(...) will return True, the second will use the next entry in the queue (or raise UnmockedInteractionError if the queue is empty).
Step 4: Enter the sandbox¶
with bigfoot: is the preferred sandbox syntax. It is shorthand for with bigfoot.sandbox():. Both forms activate all plugins for the current test. Any mock call is intercepted, recorded to the timeline, and dispatched to the configured side effect. Outside the sandbox, calling the mock raises SandboxNotActiveError.
with bigfoot: returns the active StrictVerifier from __enter__, so you can capture it if needed:
with bigfoot as v:
result = email.send(to="user@example.com", subject="Welcome")
# v is the StrictVerifier for this test
This is equivalent to with bigfoot.sandbox() as v:. Most tests use the module-level API (bigfoot.mock(), bigfoot.assert_interaction(), etc.) and never need v directly. The main case where you need it is registering custom plugins manually:
import bigfoot
from myapp.plugins import DatabasePlugin
def test_with_custom_plugin():
with bigfoot as v:
db = DatabasePlugin(v) # register plugin on this verifier
db.mock_query("SELECT 1", result=[1])
...
Step 5: Assert interactions¶
Assertions must happen after the sandbox exits. assert_interaction() takes a source object (a MethodProxy or bigfoot.http.request) and keyword arguments that must match the recorded interaction's details dict. By default it checks the next unasserted interaction in sequence order. Use bigfoot.in_any_order() to relax ordering.
Step 6: Verify all (automatic in pytest)¶
In pytest, verify_all() is called automatically at teardown. It checks that:
- Every interaction in the timeline has been asserted (no
UnassertedInteractionsError) - Every required mock is consumed (no
UnusedMocksError)
When constructing StrictVerifier manually (outside pytest), call verify_all() yourself.
What each error looks like¶
UnmockedInteractionError¶
Raised immediately when a mock method is called with an empty queue.
UnmockedInteractionError: source_id='mock:EmailService.send', args=(), kwargs={'to': 'user@example.com'},
hint='Unexpected call to EmailService.send
Called with: args=(), kwargs={'to': 'user@example.com'}
To mock this interaction, add before your sandbox:
bigfoot.mock("EmailService").send.returns(<value>)
Or to mark it optional:
bigfoot.mock("EmailService").send.required(False).returns(<value>)'
UnassertedInteractionsError¶
Raised at teardown when at least one recorded interaction was never matched by assert_interaction().
UnassertedInteractionsError: 1 unasserted interaction(s), hint='1 interaction(s) were not asserted
[sequence=0] [MockPlugin] EmailService.send
To assert this interaction:
bigfoot.assert_interaction(bigfoot.mock("EmailService").send)
'
UnusedMocksError¶
Raised at teardown when a required=True mock was registered but never called.
UnusedMocksError: 1 unused mock(s), hint='1 mock(s) were registered but never triggered
mock:EmailService.send
Mock registered at:
File "test_email.py", line 5, in test_welcome_email
email.send.returns(True)
Options:
- Remove this mock if it's not needed
- Mark it optional: bigfoot.mock("EmailService").send.required(False).returns(...)
'
VerificationError¶
Raised at teardown when both UnassertedInteractionsError and UnusedMocksError apply simultaneously. The error contains both sub-errors as .unasserted and .unused attributes.
AssertionInsideSandboxError¶
Raised when assert_interaction(), in_any_order(), or verify_all() is called while a sandbox is still active. Assertions must happen after the sandbox exits.