Skip to content

useSpyOn (JavaScript)

Language JavaScript (and super languages)
biome.json
{
"linter": {
"rules": {
"nursery": {
"useSpyOn": "error"
}
}
}
}

Enforce using jest.spyOn() or vi.spyOn() instead of overwriting a property with a mock function.

When a property is replaced with jest.fn() or vi.fn(), the original value is lost. It has to be saved and put back by hand after the test, otherwise the mock leaks into other tests. A mock created with jest.spyOn() or vi.spyOn() remembers the original value, so it can be restored with mockRestore(), restoreAllMocks(), or the restoreMocks setting of the test runner.

A spy calls the original function until you give it another implementation, for example with mockImplementation() or mockReturnValue().

The fix is unsafe because spyOn() throws an error when the property doesn’t exist or isn’t a function, while the assignment always succeeds.

Date.now = jest.fn();
code-block.js:1:1 lint/nursery/useSpyOn  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ℹ This assignment replaces a property with a mock function.

> 1 │ Date.now = jest.fn();
│ ^^^^^^^^^^^^^^^^^^^^
2 │

ℹ The original value of the property is lost, so it has to be put back by hand after the test.

ℹ Use jest.spyOn() instead, so the original value can be restored with mockRestore() or restoreAllMocks().

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

ℹ Unsafe fix: Use jest.spyOn() instead.

1 │ - Date.now·=·jest.fn();
1 │ + jest.spyOn(Date,·"now").mockImplementation();
2 2 │

Date.now = vi.fn(() => 10);
code-block.js:1:1 lint/nursery/useSpyOn  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ℹ This assignment replaces a property with a mock function.

> 1 │ Date.now = vi.fn(() => 10);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

ℹ The original value of the property is lost, so it has to be put back by hand after the test.

ℹ Use vi.spyOn() instead, so the original value can be restored with mockRestore() or restoreAllMocks().

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

ℹ Unsafe fix: Use vi.spyOn() instead.

1 │ - Date.now·=·vi.fn(()·=>·10);
1 │ + vi.spyOn(Date,·"now").mockImplementation(()·=>·10);
2 2 │

window.fetch = jest.fn().mockResolvedValue(response);
code-block.js:1:1 lint/nursery/useSpyOn  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ℹ This assignment replaces a property with a mock function.

> 1 │ window.fetch = jest.fn().mockResolvedValue(response);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

ℹ The original value of the property is lost, so it has to be put back by hand after the test.

ℹ Use jest.spyOn() instead, so the original value can be restored with mockRestore() or restoreAllMocks().

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

ℹ Unsafe fix: Use jest.spyOn() instead.

1 │ - window.fetch·=·jest.fn().mockResolvedValue(response);
1 │ + jest.spyOn(window,·"fetch").mockImplementation().mockResolvedValue(response);
2 2 │

jest.spyOn(Date, "now");
jest.spyOn(Date, "now").mockImplementation(() => 10);
vi.spyOn(window, "fetch").mockResolvedValue(response);
const mock = jest.fn();
const mocks = { now: vi.fn() };