Background
There is no supported way to test that a custom assertion fails the way you intended. To check its failure output you have to reconstruct the expected string from an internal renderer.
bashunit's own suite does exactly that, in tests/functional/custom_asserts_test.sh:
function test_assert_foo_failed() {
assert_same "$(bashunit::console_results::print_failed_test "Assert foo failed" "foo" "but got " "bar")" \
"$(assert_foo "bar")"
}
tests/unit/custom_assertions_test.sh goes further and monkey-patches bashunit::console_results::print_line inside a subshell to capture output.
If the framework has to break its own encapsulation to test a custom assertion, a user has no chance. It also means any change to the failure renderer breaks those tests for reasons unrelated to the assertion under test.
Proposal
Two assertions for asserting about assertions:
assert_assertion_fails <cmd> [args...]
assert_assertion_passes <cmd> [args...]
Each one runs the command with the assertion counters snapshotted, restores them afterwards so the inner assertion does not pollute the test's own totals, and reports a single assertion of its own.
function test_assert_positive_number_rejects_zero() {
assert_assertion_fails assert_positive_number 0
}
function test_assert_positive_number_accepts_one() {
assert_assertion_passes assert_positive_number 1
}
An optional message check keeps the output contract testable without touching console_results:
assert_assertion_fails_with "positive number" assert_positive_number 0
Notes
- The counter snapshot and restore is the load-bearing part. Without it, the inner failure leaves
_BASHUNIT_ASSERTION_FAILED_IN_TEST set, and every later assertion in the same test is skipped when stop-on-assertion-failure is on (src/assert.sh:10).
- Once this exists,
tests/functional/custom_asserts_test.sh and tests/unit/custom_assertions_test.sh should be rewritten on top of it, which is the real proof that the API is good enough.
Part of a custom-asserts DX set, each sized as its own PR:
Background
There is no supported way to test that a custom assertion fails the way you intended. To check its failure output you have to reconstruct the expected string from an internal renderer.
bashunit's own suite does exactly that, in
tests/functional/custom_asserts_test.sh:tests/unit/custom_assertions_test.shgoes further and monkey-patchesbashunit::console_results::print_lineinside a subshell to capture output.If the framework has to break its own encapsulation to test a custom assertion, a user has no chance. It also means any change to the failure renderer breaks those tests for reasons unrelated to the assertion under test.
Proposal
Two assertions for asserting about assertions:
Each one runs the command with the assertion counters snapshotted, restores them afterwards so the inner assertion does not pollute the test's own totals, and reports a single assertion of its own.
An optional message check keeps the output contract testable without touching
console_results:assert_assertion_fails_with "positive number" assert_positive_number 0Notes
_BASHUNIT_ASSERTION_FAILED_IN_TESTset, and every later assertion in the same test is skipped when stop-on-assertion-failure is on (src/assert.sh:10).tests/functional/custom_asserts_test.shandtests/unit/custom_assertions_test.shshould be rewritten on top of it, which is the real proof that the API is good enough.Part of a custom-asserts DX set, each sized as its own PR:
bashunit doc#918 listing project assertions inbashunit doc