AssertJ Consumer Argument Makes No Assertion
ID |
java.assertj_assertions_consumer_args_contain |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Java |
Tags |
reliability, testing |
Description
Reports an AssertJ satisfies-family call — allSatisfy, anySatisfy, hasOnlyOneElementSatisfying, isInstanceOfSatisfying, noneSatisfy, satisfies, satisfiesAnyOf or zipSatisfy — whose inline lambda argument makes no assertion anywhere in its body.
Rationale
These methods hand the element under test to the lambda and expect the lambda itself to verify it — there is no assertion around the call. A lambda that only evaluates a boolean expression or reads a value, without asserting on it, silently checks nothing: the test passes regardless of what the element actually contains.
assertThat(team).allSatisfy(player -> player.name().length() > 0);
Remediation
Assert on the value inside the lambda instead of merely computing one.
assertThat(team).allSatisfy(player -> assertThat(player.name()).isNotEmpty());
What is not reported
A lambda counts as asserting when it calls anything named like an assertion — a name starting with assert or verify — not only the assertion APIs known by fully-qualified name. Generated AssertJ *Assert classes, a project’s own Assertions facade and hand-written assertSomething(…) helpers all check the object, so a consumer that calls one is not reported.
Only an inline lambda passed directly as the argument is inspected. A method reference (for example "x"::equals) or a Consumer held in a variable or field is left alone: distinguishing one that ultimately asserts from one that does not would need type information this rule does not have, so nothing is reported either way rather than guessing. satisfies(Condition) is a different overload, taking a Condition object rather than a Consumer, and is out of scope.