Assertion Comparing an Expression With Itself
ID |
javascript.assertions_compare_object_itself |
Severity |
critical |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Reliability |
Language |
JavaScript |
Tags |
reliability, suspicious-comparison, testing |
Description
Reports an assertion whose two compared expressions are the same expression: expect(shipment).toEqual(shipment), assert.strictEqual(total, total). Such an assertion holds by construction and can never fail.
Only stable expressions are compared: a name, a property path, this.x.y. An expression carrying a call, an allocation, an assignment or an increment is never treated as stable, because two syntactically identical occurrences of one of those can evaluate to different values — expect(nextId()).toBe(nextId()) is a real, and failing, assertion. The two sides are compared as parsed-token sequences, so comments and spacing between them make no difference.
Exception: a test whose own title says it is about equality or identity is left alone, since comparing a value with itself is how ===, equals and a custom comparator are legitimately validated. The exception is scoped to the equality comparators, not to every matcher.
Rationale
// Bad
it('applies the discount', () => {
const order = priced(['pen']);
expect(order.total).toBe(order.total); // holds whatever discount() did
});
-
The assertion passes on every run, so the behaviour it was written for is not checked at all.
-
It is almost always a copy-paste in which one side was meant to be the expected value, and the mistake survives review because both sides read as the thing under test.
-
Unlike a missing assertion, this one is not merely absent — it is present and green, which is what stops anyone from adding the real check.
-
A test full of these reports full coverage of the module, which makes the gap invisible to every instrument a team has.
Remediation
Put the expected value on one side.
// Good
it('applies the discount', () => {
const order = priced(['pen']);
expect(order.total).toBe(9.5);
});
Where the point really is that a value equals itself — validating a comparator — say so in the title, which is what makes the assertion legible as deliberate.
// Good — the title documents the intent
it('is equal to itself', () => {
expect(order).toEqual(order);
});