Skip to content

Commit 6691890

Browse files
committed
Add Test Timing-Based Code With Jest Fake Timers as a javascript til
1 parent 8159d04 commit 6691890

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ and pairing with smart people at Hashrocket.
99

1010
For a steady stream of TILs, [sign up for my newsletter](https://tinyletter.com/jbranchaud).
1111

12-
_935 TILs and counting..._
12+
_936 TILs and counting..._
1313

1414
---
1515

@@ -354,6 +354,7 @@ _935 TILs and counting..._
354354
- [String Interpolation With Template Literals](javascript/string-interpolation-with-template-literals.md)
355355
- [Support Nested Matching In Custom Jest Matchers](javascript/support-nested-matching-in-custom-jest-matchers.md)
356356
- [Test Coverage Stats With Jest](javascript/test-coverage-stats-with-jest.md)
357+
- [Test Timing-Based Code With Jest Fake Timers](javascript/test-timing-based-code-with-jest-fake-timers.md)
357358
- [The Comma Operator](javascript/the-comma-operator.md)
358359
- [Throttling A Function Call](javascript/throttling-a-function-call.md)
359360
- [Timing Processes](javascript/timing-processes.md)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Test Timing-Based Code With Jest Fake Timers
2+
3+
In real-world code we use timeouts to do things like debouncing and throttling
4+
of functions. This is really hard to test efficently and accurately with basic
5+
test runner tooling.
6+
7+
Jest, however, offers some [Timer Mock
8+
tooling](https://jestjs.io/docs/en/timer-mocks) that removes most of the
9+
complexity of getting this right.
10+
11+
Here is a method to test:
12+
13+
```javascript
14+
const doSomethingAfter200ms = doSomething => {
15+
setTimeout(() => {
16+
doSomething();
17+
}, 200);
18+
};
19+
```
20+
21+
A test that shows this to work would have to observe `doSomething` getting
22+
called after 200ms.
23+
24+
The following test won't work because the expectation is evaluated before the
25+
timeout function is triggered.
26+
27+
```javascript
28+
describe("doSomethingAfter200ms", () => {
29+
test("does something after 200ms (fail)", () => {
30+
const doSomething = jest.fn();
31+
32+
doSomethingAfter200ms(doSomething);
33+
34+
expect(doSomething).toHaveBeenCalled();
35+
});
36+
});
37+
```
38+
39+
By activating `jest.useFakeTimers()`, we can simulate the passing of 200ms and
40+
then check that our mocked function was called.
41+
42+
```javascript
43+
jest.useFakeTimers();
44+
45+
describe("doSomethingAfter200ms", () => {
46+
test("does something after 200ms (pass)", () => {
47+
const doSomething = jest.fn();
48+
49+
doSomethingAfter200ms(doSomething);
50+
51+
jest.advanceTimersByTime(201);
52+
53+
expect(doSomething).toHaveBeenCalled();
54+
});
55+
});
56+
```
57+
58+
Jest's function mocks and timer mocks make this possible.

0 commit comments

Comments
 (0)