# jest/prefer-spy-on

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

`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.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. To turn it on:

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

{/* End of the generated section. */}

## Examples

Reported:

{/* bad {"count": 2} */}
```ts
import { beforeEach, jest } from "@jest/globals";

beforeEach(() => {
  Date.now = jest.fn(() => 1700000000000);
  console.warn = jest.fn();
});
```

Not reported:

{/* good */}
```ts
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:

{/* good */}
```ts
import { jest } from "@jest/globals";

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