From ab42bbd7e12798f063de66886e3a32bca4d657f2 Mon Sep 17 00:00:00 2001 From: Matan Borenkraout Date: Mon, 20 Jul 2020 13:34:03 +0300 Subject: [PATCH 1/7] docs(fakeTimers): Explain how to use fake timers in testing-library Relates to https://github.com/testing-library/react-testing-library/pull/743 --- docs/using-fake-timers.md | 33 +++++++++++++++++++++++++++++++++ website/sidebars.json | 2 +- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 docs/using-fake-timers.md diff --git a/docs/using-fake-timers.md b/docs/using-fake-timers.md new file mode 100644 index 00000000..c9203fc1 --- /dev/null +++ b/docs/using-fake-timers.md @@ -0,0 +1,33 @@ +--- +id: using-fake-timers +title: Using Fake Timers +sidebar_label: Using Fake Timers +--- + +Using real timers in your tests is less common since they depend on real time +lapse. For that, some testing frameworks offer the option to use fake timers in +your tests so you won't need to depend on real times. + +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`, here's an example of how to do that in jest: + +```js +beforeEach(() => { + jest.useFakeTimers() +}) +``` + +When doing so, you'll probably want to restore the timers after your test runs. +For that you usually call `useRealTimers` in `afterEach`. It's important to +remember that before calling `useRealTimers` you have to `clearAllTimers`. This +will ensure you clear all the timers even if they weren't executed. That way, +your fake timers are encapsulated to your tests only and when we try to cleanup, +we will work with real timers. So you'll need to do something like this: + +```js +afterEach(() => { + jest.clearAllTimers() + jest.useRealTimers() +}) +``` diff --git a/website/sidebars.json b/website/sidebars.json index be00e320..d2dea8cb 100755 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -1,6 +1,6 @@ { "docs": { - "Getting Started": ["intro", "guiding-principles"], + "Getting Started": ["intro", "guiding-principles", "using-fake-timers"], "Frameworks": [ { "type": "subcategory", From b03c8004c332b854010716f761d730508ce79d23 Mon Sep 17 00:00:00 2001 From: Matan Borenkraout Date: Tue, 21 Jul 2020 09:22:34 +0300 Subject: [PATCH 2/7] docs(fakeTimers): Fix some phrases and use runOnlyPendingTimers. Closes #523. --- docs/using-fake-timers.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/using-fake-timers.md b/docs/using-fake-timers.md index c9203fc1..8ba7ded3 100644 --- a/docs/using-fake-timers.md +++ b/docs/using-fake-timers.md @@ -5,8 +5,8 @@ sidebar_label: Using Fake Timers --- Using real timers in your tests is less common since they depend on real time -lapse. For that, some testing frameworks offer the option to use fake timers in -your tests so you won't need to depend on real times. +lapse. For that, most testing frameworks offer the option to use fake timers in +your tests so you won't need to rely on real times. 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 @@ -20,14 +20,15 @@ beforeEach(() => { When doing so, you'll probably want to restore the timers after your test runs. For that you usually call `useRealTimers` in `afterEach`. It's important to -remember that before calling `useRealTimers` you have to `clearAllTimers`. This -will ensure you clear all the timers even if they weren't executed. That way, -your fake timers are encapsulated to your tests only and when we try to cleanup, -we will work with real timers. So you'll need to do something like this: +remember that before calling `useRealTimers` you should call +`runOnlyPendingTimers`. This will ensure you progress all pending timers so non +of them are left hanging and don't get executed. +That way,your fake timers are encapsulated to your tests only and all of them +behave as you would expect. Here's an example of doing that in jest: ```js afterEach(() => { - jest.clearAllTimers() + jest.runOnlyPendingTimers() jest.useRealTimers() }) ``` From bf684ae3c22c551334ebd941fc7a5cb3908e33c2 Mon Sep 17 00:00:00 2001 From: Matan Borenkraout Date: Tue, 21 Jul 2020 09:30:41 +0300 Subject: [PATCH 3/7] docs(fakeTimers): Add a missing space and fix phrasing --- docs/using-fake-timers.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/using-fake-timers.md b/docs/using-fake-timers.md index 8ba7ded3..063d75db 100644 --- a/docs/using-fake-timers.md +++ b/docs/using-fake-timers.md @@ -5,12 +5,12 @@ sidebar_label: Using Fake Timers --- Using real timers in your tests is less common since they depend on real time -lapse. For that, most testing frameworks offer the option to use fake timers in -your tests so you won't need to rely on real times. +lapse. To solve this, most testing frameworks offer the option to use fake +timers in your tests so you won't need to rely on real times. 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`, here's an example of how to do that in jest: +`beforeEach`, here's an example of how to do that using jest: ```js beforeEach(() => { @@ -21,10 +21,10 @@ beforeEach(() => { When doing so, you'll probably want to restore the timers after your test runs. For that you usually call `useRealTimers` in `afterEach`. It's important to remember that before calling `useRealTimers` you should call -`runOnlyPendingTimers`. This will ensure you progress all pending timers so non +`runOnlyPendingTimers`. This will ensure you progress all pending timers so none of them are left hanging and don't get executed. -That way,your fake timers are encapsulated to your tests only and all of them -behave as you would expect. Here's an example of doing that in jest: +That way, your fake timers are encapsulated to your tests only and all of them +behave as you would expect. Here's an example of doing that using jest: ```js afterEach(() => { From f73c0fddb814ec0a7937f8fa62a7e316cfc28ac1 Mon Sep 17 00:00:00 2001 From: Matan Borenkraout Date: Wed, 22 Jul 2020 09:19:11 +0300 Subject: [PATCH 4/7] docs(fakeTimers): Multiple fixes for adding fake timers page after review --- docs/using-fake-timers.md | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/docs/using-fake-timers.md b/docs/using-fake-timers.md index 063d75db..d0483789 100644 --- a/docs/using-fake-timers.md +++ b/docs/using-fake-timers.md @@ -4,29 +4,44 @@ title: Using Fake Timers sidebar_label: Using Fake Timers --- -Using real timers in your tests is less common since they depend on real time -lapse. To solve this, most testing frameworks offer the option to use fake +Using real timers in your tests is problematic since they depend on real time +lapse. +When you depend on real time, your tests can be unpredictable, slow, flaky. This +will will also prevent you from making any assumptions about timestamps within +your tests. + +To solve these problems, most testing frameworks offer the option to use fake timers in your tests so you won't need to rely on real times. 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`, here's an example of how to do that using jest: +timers. +The common pattern to setup fake timers is usually within the `beforeEach`, for +example: ```js +// Fake timers using Jest beforeEach(() => { jest.useFakeTimers() }) ``` -When doing so, you'll probably want to restore the timers after your test runs. -For that you usually call `useRealTimers` in `afterEach`. It's important to -remember that before calling `useRealTimers` you should call -`runOnlyPendingTimers`. This will ensure you progress all pending timers so none -of them are left hanging and don't get executed. -That way, your fake timers are encapsulated to your tests only and all of them -behave as you would expect. Here's an example of doing that using jest: +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. +For that you usually call `useRealTimers` in `afterEach`. +It's important to also call `runOnlyPendingTimers` before switching to real +timers. +This will ensure you flush all the pending timers before you switch to real +timers. If you don't progress the timers and just switch to real timers, the +scheduled tasks won't get executed and you'll get an unexpected behavior. +This is mostly important for 3rd parties that schedule tasks without you being +aware of it. +Here's an example of doing that using jest: ```js +// Running all pending timers and switching to real timers using Jest afterEach(() => { jest.runOnlyPendingTimers() jest.useRealTimers() From 52148f36b3193ad99fff20143161dfd24e164e31 Mon Sep 17 00:00:00 2001 From: Matan Borenkraout Date: Wed, 22 Jul 2020 10:54:53 +0300 Subject: [PATCH 5/7] Update docs/using-fake-timers.md Co-authored-by: Sebastian Silbermann --- docs/using-fake-timers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/using-fake-timers.md b/docs/using-fake-timers.md index d0483789..f5d8f315 100644 --- a/docs/using-fake-timers.md +++ b/docs/using-fake-timers.md @@ -7,7 +7,7 @@ sidebar_label: Using Fake Timers Using real timers in your tests is problematic since they depend on real time lapse. When you depend on real time, your tests can be unpredictable, slow, flaky. This -will will also prevent you from making any assumptions about timestamps within +will also prevent you from making any assumptions about timestamps within your tests. To solve these problems, most testing frameworks offer the option to use fake From 37eadebc01bcaed2e9089111a51640a3d03b18df Mon Sep 17 00:00:00 2001 From: Matan Borenkraout Date: Sun, 26 Jul 2020 19:54:55 +0300 Subject: [PATCH 6/7] docs(fakeTimers): Rephrase the using section to explain that fake timers should only be sporadically used. --- docs/using-fake-timers.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/using-fake-timers.md b/docs/using-fake-timers.md index d0483789..9b6e9713 100644 --- a/docs/using-fake-timers.md +++ b/docs/using-fake-timers.md @@ -4,14 +4,14 @@ title: Using Fake Timers sidebar_label: Using Fake Timers --- -Using real timers in your tests is problematic since they depend on real time -lapse. -When you depend on real time, your tests can be unpredictable, slow, flaky. This -will will also prevent you from making any assumptions about timestamps within -your tests. +In some cases, when your code uses timers (`setTimeout`, `setInterval`, +`clearTimeout`, `clearInterval`), your tests may become unpredictable, slow and +flaky. -To solve these problems, most testing frameworks offer the option to use fake -timers in your tests so you won't need to rely on real times. +To solve these problems, or if you need to rely on specific timestamps in your +tests, 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. From 624767079c0a07ac7a8861451b0a007e36388526 Mon Sep 17 00:00:00 2001 From: Matan Borenkraout Date: Sun, 26 Jul 2020 19:57:23 +0300 Subject: [PATCH 7/7] docs(fakeTimers): Fix small typo --- docs/using-fake-timers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/using-fake-timers.md b/docs/using-fake-timers.md index 9b6e9713..a241e0ff 100644 --- a/docs/using-fake-timers.md +++ b/docs/using-fake-timers.md @@ -9,7 +9,7 @@ In some cases, when your code uses timers (`setTimeout`, `setInterval`, flaky. To solve these problems, or if you need to rely on specific timestamps in your -tests, most testing frameworks offer the option to replace the real timers in +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.