Why is this an issue?

Assertions are meant to verify behavior that depends on the code under test. When an assertion is made on a syntactically constant value, the assertion result is already known before the test runs. The test either always succeeds or always fails, so it does not provide useful feedback about the production code.

This rule raises an issue when a JavaScript assertion uses an expression that is trivially truthy, falsy, null, or undefined. 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, or new expression. Such objects are created at the assertion site and cannot be identical to a value that existed before the assertion.

How to fix it in Vitest

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.

Code examples

Noncompliant code example

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 }); // the object literal creates a new object every time
  const limit = 10 + 5;
  expect(limit).toBeTruthy(); // `limit` resolves to a constant binary expression, so the assertion always succeeds
});

Compliant solution

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

How to fix it in Node.js

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.

Code examples

Noncompliant code example

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" }); // the object literal creates a new object every time
  assert.notStrictEqual(getItems(), []); // this assertion always succeeds, the array literal creates a new object every time
  assert(false, "should not be called"); // this assertion always fails
  const expectedMode = "test";
  assert.strictEqual(expectedMode, "test"); // both sides resolve to the same constant, so the assertion always succeeds
});

Compliant solution

import assert from "node:assert";
import test from "node:test";

test("loads configuration", () => {
  assert.ok(loadConfiguration());
  assert.deepStrictEqual(readConfiguration(), { mode: "test" });
  assert.deepStrictEqual(getItems(), []);
  assert.fail("should not be called");
  const expectedMode = "test";
  assert.strictEqual(readConfiguration().mode, expectedMode);
});

How to fix it in Chai

Replace constant assertion arguments with values produced by the code under test. When comparing objects, use structural equality assertions instead of identity assertions.

Code examples

Noncompliant code example

import { assert, expect } from "chai";
import "chai/register-should";

// assert style
assert.ok("ready"); // this assertion always succeeds
assert.strictEqual(getUser(), { id: 1 }); // the object literal creates a new object every time

// expect style
expect(true).to.be.ok; // this assertion always succeeds
expect(getUser()).to.equal({ id: 1 }); // the object literal creates a new object every time

// should style
"done".should.be.ok; // this assertion always succeeds
getUser().should.equal({ id: 1 }); // the object literal creates a new object every time

const negated = !true;
expect(negated).to.be.false; // `negated` resolves to a unary expression on a constant, so the assertion always succeeds

Compliant solution

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;

Resources

Documentation