Assertions are meant to verify behavior that depends on the code under test. When an assertion is made on a syntactically constant value that is guaranteed to make it succeed, the outcome no longer depends on the code under test: the assertion always passes, so it silently stops testing anything without ever failing to draw attention to it.
This rule raises an issue when a JavaScript assertion uses an expression that is trivially truthy, falsy, null, or
undefined in a way that always makes the assertion succeed, taking .not and other negations into account.
It also raises an issue when an identity assertion compares a value with a freshly-created object, such as an object literal, array literal,
function expression, class expression, new expression, or regular expression literal. Such objects are created at the assertion site and
can never be identical to a value that existed before it, so the comparison result is always known in advance, whether the assertion is expected to
succeed or fail. This is a common toBe/toEqual (or strictEqual/deepStrictEqual) mixup, so it is
flagged regardless of which way it makes the assertion resolve.
Replace the constant assertion argument with a value produced by the code under test. When testing objects or arrays, use a structural equality matcher instead of an identity matcher if the expected value is newly created in the assertion.
import { expect, test } from "vitest";
test("checks user state", () => {
expect(true).toBeTruthy(); // this assertion always succeeds
expect(undefined).not.toBeDefined(); // this assertion always succeeds
expect([]).toBeTruthy(); // this assertion always succeeds
expect(class User {}).toBeTruthy(); // this assertion always succeeds
expect(getUser()).toBe({ id: 1 }); // freshly-created objects are never identical to other values; likely meant toEqual
const limit = 10 + 5;
expect(limit).toBeTruthy(); // `limit` resolves to a constant binary expression, so the assertion always succeeds
});
import { expect, test } from "vitest";
test("checks user state", () => {
expect(isReady()).toBeTruthy();
expect(findUser("missing")).not.toBeDefined();
expect(getItems()).toHaveLength(0);
expect(getUser()).toEqual({ id: 1 });
const limit = computeLimit();
expect(limit).toBeTruthy();
});
Replace assertions on literal or otherwise syntactically constant expressions with assertions on values returned by the code under test. When checking newly-created expected objects, use deep equality assertions instead of identity assertions.
import assert from "node:assert";
import test from "node:test";
test("loads configuration", () => {
assert.ok("ready"); // this assertion always succeeds
assert.ok(function handler() {}); // this assertion always succeeds
assert.strictEqual(readConfiguration(), { mode: "test" }); // freshly-created objects are never identical to other values; likely meant deepStrictEqual
assert.notStrictEqual(getItems(), []); // this assertion always succeeds, the array literal creates a new object every time
const expectedMode = "test";
assert.strictEqual(expectedMode, "test"); // both sides resolve to the same constant, so the assertion always succeeds
});
import assert from "node:assert";
import test from "node:test";
test("loads configuration", () => {
assert.ok(loadConfiguration());
assert.deepStrictEqual(readConfiguration(), { mode: "test" });
assert.deepStrictEqual(getItems(), []);
const expectedMode = "test";
assert.strictEqual(readConfiguration().mode, expectedMode);
});
Replace constant assertion arguments with values produced by the code under test. When comparing objects, use structural equality assertions instead of identity assertions.
import { assert, expect } from "chai";
import "chai/register-should";
// assert style
assert.ok("ready"); // this assertion always succeeds
assert.strictEqual(getUser(), { id: 1 }); // freshly-created objects are never identical to other values; likely meant deepEqual
// expect style
expect(true).to.be.ok; // this assertion always succeeds
expect(getUser()).to.equal({ id: 1 }); // freshly-created objects are never identical to other values; likely meant deep.equal
// should style
"done".should.be.ok; // this assertion always succeeds
getUser().should.equal({ id: 1 }); // freshly-created objects are never identical to other values; likely meant deep.equal
const negated = !true;
expect(negated).to.be.false; // `negated` resolves to a unary expression on a constant, so the assertion always succeeds
import { assert, expect } from "chai";
import "chai/register-should";
// assert style
assert.ok(loadConfiguration());
assert.deepEqual(getUser(), { id: 1 });
// expect style
expect(isReady()).to.be.ok;
expect(getUser()).to.deep.equal({ id: 1 });
// should style
isReady().should.be.ok;
getUser().should.deep.equal({ id: 1 });
const negated = !isFeatureEnabled();
expect(negated).to.be.false;
expectexpectTest runnershould