Assertion Compares An Expression With Itself
ID |
php.assertions_compare_object_itself |
Severity |
critical |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Reliability |
Language |
Php |
Tags |
reliability, suspicious-comparison, testing |
Description
Reports a PHPUnit assertion whose two compared expressions are the same expression, such as
assertSame($opening, $opening). The assertion holds by construction and can never fail, whatever
the code under test does.
Rationale
An assertion that compares a value with itself is green from the moment it is written and stays green forever. It is almost always a copy-paste in which one side was meant to name the expected value — a sibling variable, a literal, a figure computed independently — and what looks like a covered behaviour is not covered at all.
<?php
$opening = 100.0;
$this->assertSame($opening, $opening); // FLAW — cannot fail
$this->assertEquals($this->entries, $this->entries); // FLAW — cannot fail
$this->assertGreaterThan($this->total, $this->total); // FLAW — cannot ever be true
$this->assertSame($opening, $this->subject->total()); // OK — distinct operands
$this->assertSame($this->subject->total(), $this->subject->total()); // OK — two calls may differ
Only expressions that cannot vary are compared: a variable, a property path, an array element, a
constant. An expression carrying a call, an allocation, a clone, an assignment, an increment or a
closure is never compared, because two syntactically identical occurrences of one of those can
evaluate to different values. The two sides are compared as parsed-token sequences, so comments and
spacing between them make no difference.
A test whose own name says it is about equality, identity or hashing is left alone, since comparing a value with itself is how reflexive equality and a hash function are legitimately validated:
<?php
public function testBalanceEqualsItself(): void
{
$balance = $this->subject->snapshot();
$this->assertEquals($balance, $balance); // OK — validating reflexive equality
}
That exception is scoped to the equality comparators. The ordering ones — assertGreaterThan and
its family — stay reported, because a value is never legitimately asserted to be greater than
itself.
Remediation
Work out which side was meant to be the expected value and write it. If the assertion is genuinely redundant, delete it rather than leave a check that cannot fail.
<?php
$opening = 100.0;
$this->subject->post(new Entry('books', 12.50));
$this->assertSame($opening + 12.50, $this->subject->total());