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());

© 2026 Xygeni. All rights reserved