Context
assert_have_been_called_with <spy> <expected> checks the last recorded call
(tail -n 1, src/test_doubles.sh:159). There is no way to assert "this spy was
called with these arguments at some point", which is the common intent when the
command under test invokes the same helper several times.
The workaround is to know the exact index and use
assert_have_been_called_with <spy> <expected> <n> or
assert_have_been_called_nth_with <n> <spy> <expected> — which couples the test
to call ordering that is usually irrelevant.
Evidence
function test_called_with_only_checks_last_call() {
bashunit::spy touch
touch first
touch second
assert_have_been_called_with touch "first" # FAILS: Expected 'first' but got 'second'
}
Nothing in the message says "checked the last call only", so the failure reads
like the call never happened.
Proposal
Add an any-call assertion, e.g.
assert_have_been_called_with_any <spy> <expected> (name open to discussion),
that scans every recorded line and passes if any matches.
Two smaller alternatives, if a new assertion is judged too much surface:
- accept a literal
any in the index position:
assert_have_been_called_with touch "first" any
- keep the assertion count as-is and only fix the message to state which call was
compared (but got 'second' (last of 2 calls))
Recommendation: ship the new assertion and the clearer message. The message
fix is worth having regardless of which matcher the user picked.
Why this matters for agentic coding
Order-coupled assertions are a maintenance tax an agent pays repeatedly: it adds
a log line to a function, an unrelated assert_have_been_called_with breaks, and
the failure text points at neither the cause nor the fix. An any-call matcher lets
an agent write the assertion that expresses the actual requirement, which is
almost always "this side effect happened", not "this side effect happened last".
Acceptance criteria
Context
assert_have_been_called_with <spy> <expected>checks the last recorded call(
tail -n 1,src/test_doubles.sh:159). There is no way to assert "this spy wascalled with these arguments at some point", which is the common intent when the
command under test invokes the same helper several times.
The workaround is to know the exact index and use
assert_have_been_called_with <spy> <expected> <n>orassert_have_been_called_nth_with <n> <spy> <expected>— which couples the testto call ordering that is usually irrelevant.
Evidence
Nothing in the message says "checked the last call only", so the failure reads
like the call never happened.
Proposal
Add an any-call assertion, e.g.
assert_have_been_called_with_any <spy> <expected>(name open to discussion),that scans every recorded line and passes if any matches.
Two smaller alternatives, if a new assertion is judged too much surface:
anyin the index position:assert_have_been_called_with touch "first" anycompared (
but got 'second' (last of 2 calls))Recommendation: ship the new assertion and the clearer message. The message
fix is worth having regardless of which matcher the user picked.
Why this matters for agentic coding
Order-coupled assertions are a maintenance tax an agent pays repeatedly: it adds
a log line to a function, an unrelated
assert_have_been_called_withbreaks, andthe failure text points at neither the cause nor the fix. An any-call matcher lets
an agent write the assertion that expresses the actual requirement, which is
almost always "this side effect happened", not "this side effect happened last".
Acceptance criteria
assert_have_been_called_withstates which call itcompared
tests/functional/doubles_test.shfor match-on-first,match-on-middle, and no-match
docs/test-doubles.md,docs/public/bashunit-skill.mdanddocs/ai-agents.md(the argument-order table)make sa+make lintgreen