Assert Side Effect
ID |
java.no_side_effect_in_assert |
Severity |
high |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Code Smell |
Language |
Java |
Tags |
assertion, code_smell, side-effect |
Description
Reports an assert statement whose condition mutates program state — through an assignment, an
increment/decrement operator, or a call to a method whose name reads as a mutator (add,
remove, set, and similar verbs). The JVM only evaluates assert conditions when started with
-ea; a mutation that lives inside one therefore runs during testing and silently stops running
in a default production start-up.
Rationale
private int retries;
void check(Queue<String> queue) {
assert ++retries < MAX_RETRIES; // FLAW — the increment disappears without -ea
assert queue.remove("stale"); // FLAW — the removal disappears without -ea
}
With assertions enabled, retries is incremented and the stale entry is removed every time this
method runs; with assertions disabled — the JVM default — neither happens, and the rest of the
program now behaves differently depending on a flag nobody remembers to set consistently between
a developer’s machine and a server.
Remediation
Move the mutation out of the condition so it always runs, and assert on the resulting value instead.
private int retries;
void check(Queue<String> queue) {
retries++;
assert retries < MAX_RETRIES; // OK — the increment always happens
boolean removed = queue.remove("stale");
assert removed; // OK — the removal always happens
}