There is an example on advanced-hooks#async doc.
I am confused about how does waitForNextUpdate
works. I made two test cases to compare waitForNextUpdate
and act()
+ jest.advanceTimersByTime()
.
index.ts
:
import { useState, useCallback } from 'react';
export function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue);
const increment = () => setCount((x) => x + 1);
const incrementAsync = useCallback(() => setTimeout(increment, 100, [increment]);
const reset = useCallback(() => setCount(initialValue), [initialValue]);
return { count, increment, incrementAsync, reset };
}
index.test.ts
:
import { renderHook, act } from '@testing-library/react-hooks';
import { useCounter } from './';
jest.setTimeout(5 * 1000);
describe('waitForNextUpdate V.S. jest-advancedTimersByTime', () => {
test('should pass by using jest.advancedTimersByTime', () => {
jest.useFakeTimers();
const { result } = renderHook(() => useCounter());
result.current.incrementAsync();
act(() => {
jest.advanceTimersByTime(100);
});
expect(result.current.count).toBe(1);
jest.useRealTimers();
});
test('should pass by using waitForNextUpdate', async () => {
const { result, waitForNextUpdate } = renderHook(() => useCounter());
result.current.incrementAsync();
await waitForNextUpdate();
expect(result.current.count).toBe(1);
});
});
Test result:
PASS issues/waitForNextUpdate-vs-jest-advancedTimersByTime/index.test.ts
waitForNextUpdate V.S. jest-advancedTimersByTime
✓ should pass by using jest.advancedTimersByTime (13 ms)
✓ should pass by using waitForNextUpdate (107 ms)
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 1.373 s, estimated 14 s
Both test cases pass. The only difference I found is that if I increase the delay for setTimeout
to 1000 * 10
, the test case which uses waitForNextUpdate
will fail.
// useCounter
//...
const incrementAsync = useCallback(() => setTimeout(increment, 1000 * 10), [increment]);
//...
// first test case
// ...
jest.advanceTimersByTime(1000 * 10);
// ...
FAIL issues/waitForNextUpdate-vs-jest-advancedTimersByTime/index.test.ts (10.554 s)
waitForNextUpdate V.S. jest-advancedTimersByTime
✓ should pass by using jest.advancedTimersByTime (19 ms)
✕ should pass by using waitForNextUpdate (1006 ms)
● waitForNextUpdate V.S. jest-advancedTimersByTime › should pass by using waitForNextUpdate
Timed out in waitForNextUpdate after 1000ms.
at waitForNextUpdate (node_modules/@testing-library/react-hooks/lib/core/asyncUtils.js:102:13)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 passed, 2 total
Snapshots: 0 total
Time: 11.112 s
So what's the difference between waitForNextUpdate
and act()
+ jest.advanceTimersByTime()
? What kind of scene I can only use waitForNextupdate
rather than act()
+ jest.advanceTimersByTime()
?
package versions:
"@testing-library/react-hooks": "^5.0.0",
"jest": "^26.6.3",
"react": "^16.14.0"
incrementAsync
is missing a closing bracket on setTimeout. – Tourist