iT邦幫忙

2023 iThome 鐵人賽

DAY 11
0

來寫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() 用於立即執行所有模擬定時器。
這樣你就可以在不用等待的情況下,測試定時器相關的邏輯是否正確。


上一篇
[Day 10] 來撰寫useTimeout吧
下一篇
[Day 12] useDebounce介紹
系列文
React進階班,用typescript與jest製作自己的custom hooks庫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言