sli*_*wp2 8 reactjs jestjs react-hooks react-hooks-testing-library
Advanced-hooks#async文档上有一个示例。
\n我对如何waitForNextUpdate运作感到困惑。我做了两个测试用例来比较waitForNextUpdate和act()+ jest.advanceTimersByTime()。
index.ts:
import { useState, useCallback } from \'react\';\n\nexport function useCounter(initialValue = 0) {\n const [count, setCount] = useState(initialValue);\n const increment = () => setCount((x) => x + 1);\n const incrementAsync = useCallback(() => setTimeout(increment, 100, [increment]);\n const reset = useCallback(() => setCount(initialValue), [initialValue]);\n return { count, increment, incrementAsync, reset };\n}\nRun Code Online (Sandbox Code Playgroud)\nindex.test.ts:
import { renderHook, act } from \'@testing-library/react-hooks\';\nimport { useCounter } from \'./\';\n\njest.setTimeout(5 * 1000);\n\ndescribe(\'waitForNextUpdate V.S. jest-advancedTimersByTime\', () => {\n test(\'should pass by using jest.advancedTimersByTime\', () => {\n jest.useFakeTimers();\n const { result } = renderHook(() => useCounter());\n result.current.incrementAsync();\n act(() => {\n jest.advanceTimersByTime(100);\n });\n expect(result.current.count).toBe(1);\n jest.useRealTimers();\n });\n\n test(\'should pass by using waitForNextUpdate\', async () => {\n const { result, waitForNextUpdate } = renderHook(() => useCounter());\n result.current.incrementAsync();\n await waitForNextUpdate();\n expect(result.current.count).toBe(1);\n });\n});\nRun Code Online (Sandbox Code Playgroud)\n测试结果:
\n PASS issues/waitForNextUpdate-vs-jest-advancedTimersByTime/index.test.ts\n waitForNextUpdate V.S. jest-advancedTimersByTime\n \xe2\x9c\x93 should pass by using jest.advancedTimersByTime (13 ms)\n \xe2\x9c\x93 should pass by using waitForNextUpdate (107 ms)\n\nTest Suites: 1 passed, 1 total\nTests: 2 passed, 2 total\nSnapshots: 0 total\nTime: 1.373 s, estimated 14 s\nRun Code Online (Sandbox Code Playgroud)\n两个测试用例都通过。setTimeout我发现的唯一区别是,如果我增加to的延迟1000 * 10,使用的测试用例waitForNextUpdate将会失败。
import { useState, useCallback } from \'react\';\n\nexport function useCounter(initialValue = 0) {\n const [count, setCount] = useState(initialValue);\n const increment = () => setCount((x) => x + 1);\n const incrementAsync = useCallback(() => setTimeout(increment, 100, [increment]);\n const reset = useCallback(() => setCount(initialValue), [initialValue]);\n return { count, increment, incrementAsync, reset };\n}\nRun Code Online (Sandbox Code Playgroud)\n// first test case\n// ...\njest.advanceTimersByTime(1000 * 10);\n// ...\nRun Code Online (Sandbox Code Playgroud)\nimport { renderHook, act } from \'@testing-library/react-hooks\';\nimport { useCounter } from \'./\';\n\njest.setTimeout(5 * 1000);\n\ndescribe(\'waitForNextUpdate V.S. jest-advancedTimersByTime\', () => {\n test(\'should pass by using jest.advancedTimersByTime\', () => {\n jest.useFakeTimers();\n const { result } = renderHook(() => useCounter());\n result.current.incrementAsync();\n act(() => {\n jest.advanceTimersByTime(100);\n });\n expect(result.current.count).toBe(1);\n jest.useRealTimers();\n });\n\n test(\'should pass by using waitForNextUpdate\', async () => {\n const { result, waitForNextUpdate } = renderHook(() => useCounter());\n result.current.incrementAsync();\n await waitForNextUpdate();\n expect(result.current.count).toBe(1);\n });\n});\nRun Code Online (Sandbox Code Playgroud)\nwaitForNextUpdate那么和act()+之间有什么区别jest.advanceTimersByTime()?什么样的场景我只能使用waitForNextupdate而不是act()+ jest.advanceTimersByTime()?
软件包版本:
\n PASS issues/waitForNextUpdate-vs-jest-advancedTimersByTime/index.test.ts\n waitForNextUpdate V.S. jest-advancedTimersByTime\n \xe2\x9c\x93 should pass by using jest.advancedTimersByTime (13 ms)\n \xe2\x9c\x93 should pass by using waitForNextUpdate (107 ms)\n\nTest Suites: 1 passed, 1 total\nTests: 2 passed, 2 total\nSnapshots: 0 total\nTime: 1.373 s, estimated 14 s\nRun Code Online (Sandbox Code Playgroud)\n
waitForNextUpdate与时间无关,与你的钩子状态有关
由于状态更新在等待 waitForNextUpdate() 期间异步发生,因此无需将incrementAsync 包装在act() 中。异步实用程序自动将等待代码包装在异步 act() 包装器中。
Jest 的advanceTimersByTime利用实际情况setTimeout或setInterval实例:
调用此 API 时,所有计时器都会提前 msToRun 毫秒。所有已通过 setTimeout() 或 setInterval() 排队并在此时间范围内执行的待处理“宏任务”都将被执行。
| 归档时间: |
|
| 查看次数: |
4474 次 |
| 最近记录: |