jest/prefer-spy-on

Require jest.spyOn() instead of assigning jest.fn() to a property

has suggestions

Date.now = jest.fn() throws the real Date.now away. Unless you save it and put it back yourself, every test that runs afterwards gets the mock. jest.spyOn(Date, "now") remembers the original, so mockRestore() or jest.restoreAllMocks() brings it back.

--fix-suggestions rewrites obj.save = jest.fn() to jest.spyOn(obj, 'save').mockImplementation(). The .mockImplementation() is there because a spy calls the original function until you give it an implementation.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"jest/prefer-spy-on" = "error" # or "warn"

Examples#

example.ts2 problems
import { beforeEach, jest } from "@jest/globals";

beforeEach(() => {
  Date.now = jest.fn(() => 1700000000000);
  console.warn = jest.fn();
});
example.tsNo problems
import { afterEach, beforeEach, jest } from "@jest/globals";

beforeEach(() => {
  jest.spyOn(Date, "now").mockImplementation(() => 1700000000000);
  jest.spyOn(console, "warn").mockImplementation(() => {});
});

afterEach(() => {
  jest.restoreAllMocks();
});

A mock that's stored in a variable or written in an object literal doesn't replace anything, so it isn't reported:

example.tsNo problems
import { jest } from "@jest/globals";

const onSave = jest.fn();
const logger = { warn: jest.fn() };