來寫useTimeout的測試吧
這個測試滿簡單的,主要要測試三點
1.可以再秒數後執行callback function
2.如果沒設定秒數就不會執行function
3.如果component被移除(unmount),就不應該執行function
這個測試會用到新的jest方法~
useFakeTimers() 與 runAllTimers()
先來看程式碼,下面再開始解釋這兩個作用吧
import { renderHook, act } from "@testing-library/react";
import { useTimeout } from "../src";
jest.useFakeTimers();
describe("useTimeout", () => {
it("should execute callback after given delay", () => {
const callback = jest.fn();
renderHook(() => useTimeout(callback, 1000));
expect(callback).not.toBeCalled();
act(() => {
jest.runAllTimers();
});
expect(callback).toBeCalled();
expect(callback).toHaveBeenCalledTimes(1);
});
it("should not execute callback if delay is null", () => {
const callback = jest.fn();
renderHook(() => useTimeout(callback, null));
act(() => {
jest.runAllTimers();
});
expect(callback).not.toBeCalled();
});
it("should clear timeout when unmounted", () => {
const callback = jest.fn();
const { unmount } = renderHook(() => useTimeout(callback, 1000));
act(() => {
unmount();
jest.runAllTimers();
});
expect(callback).not.toBeCalled();
});
});
這兩個新方法都是 Jest 測試框架中用來模擬時間。
jest.useFakeTimers()
這個方法會模擬所有使用到的定時器功能,例如 setTimeout、setInterval 和 clearTimeout。它會拿掉 JavaScript 的原生定時器實現,然後用 Jest 自己的模擬定時器替換掉它們。這讓你能夠在測試中立即觸發這些定時器,而不需要等待它們真正地「計時」完成。
jest.runAllTimers()
當你使用了 jest.useFakeTimers() 後,所有的 setTimeout 或 setInterval 調用都會被 Jest 收集,但它們實際上不會執行,除非你明確告訴 Jest 去執行它們。
jest.runAllTimers() 就是用來做這件事的。它會立即執行所有已排隊(queued)的定時器,就像它們的延遲時間已經過去了一樣。
這兩個方法經常一起用來測試和時間相關的代碼,特別是當你不想等待定時器真的「計時」完成,而是想立即看到它們會產生什麼效果時。
簡單來說:
jest.useFakeTimers() 用於開始使用模擬的定時器。
jest.runAllTimers() 用於立即執行所有模擬定時器。
這樣你就可以在不用等待的情況下,測試定時器相關的邏輯是否正確。