Skip to content

docs: clarify fake timer usage with user-event #1391

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions docs/guides-using-fake-timers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ flaky.

To solve these problems, or if you need to rely on specific timestamps in your
code, most testing frameworks offer the option to replace the real timers in
your tests with fake ones. This should be used sporadically and not on a regular
basis since using it contains some overhead.

When using fake timers in your tests, all of the code inside your test uses fake
timers.
Comment on lines -13 to -17
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still stand by removing the This should be used sporadically and not on a regular basis since using it contains some overhead sentence. Fake timers are nothing to be scared of when used correctly. And in some cases (let's say you're developing a calendar module) they need to be used in nearly all of your tests :)

your tests with fake ones. This has a side effect - when using fake timers in
your tests, _all_ of the code inside your test uses fake timers.

The common pattern to setup fake timers is usually within the `beforeEach`, for
example:
Expand All @@ -26,12 +23,10 @@ beforeEach(() => {
})
```

When using fake timers, you need to remember to restore the timers after your
test runs.

The main reason to do that is to prevent 3rd party libraries running after your
test finishes (e.g cleanup functions), from being coupled to your fake timers
and use real timers instead.
Since fake timers are mocking native timer functions, it is necessary to restore
the timers after your test runs, just like regular mocks. This prevents fake
timers leaking into other test cases and cleanup functions, where real timers
are expected.

For that you usually call `useRealTimers` in `afterEach`.

Expand All @@ -51,3 +46,11 @@ afterEach(() => {
jest.useRealTimers()
})
```

:::note

Combining fake timers with `user-event` may cause test timeouts. Refer to
[`advanceTimers`](user-event/options.mdx#advancetimers) option to prevent this
issue.

:::
17 changes: 15 additions & 2 deletions docs/user-event/options.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,21 @@ can be applied per [`setup()`](setup.mdx).

### advanceTimers

If you are using fake timers, you need to advance your timers when we internally
[delay](#delay) subsequent code.
`user-event` adds a [delay](#delay) between some subsequent inputs. When using
[fake timers](/guides-using-fake-timers.mdx) it is necessary to set this option
to your test runner's time advancement function. For example:

```js
const user = userEvent.setup({advanceTimers: jest.advanceTimersByTime})
```

:::caution

You may find suggestions to set `delay: null` to prevent test timeouts when
using fake timers. That is not recommended, as it may cause unexpected
behaviour. Starting from v14.1, we suggest using `advanceTimers` option instead.

:::

```ts
(delay: number) => Promise<void> | void
Expand Down