bun:test/prefer-spy-on

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

has suggestions

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

The rule reports a property that's set to mock(), jest.fn() or vi.fn().

--fix-suggestions rewrites obj.save = mock() to spyOn(obj, 'save').mockImplementation() if the file imports spyOn, and 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]
"bun:test/prefer-spy-on" = "error" # or "warn"

Examples#

example.ts2 problems
import { beforeEach, jest, mock } from "bun:test";

beforeEach(() => {
  Date.now = mock(() => 1700000000000);
  console.warn = jest.fn();
});
example.tsNo problems
import { afterEach, beforeEach, mock, spyOn } from "bun:test";

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

afterEach(() => {
  mock.restore();
});

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, mock } from "bun:test";

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