今天來練習一下,如何對自己設計的 useHooks 進行測試。
(一) 建立 useHooks
(二) 認識 renderHook()
(三) 認識 act()
建立一計算±1的計算機,初始值為0,可由參數傳入,回傳一物件,包含目前數值、遞增函式、遞減函式。
import { useState } from "react";
interface CounterProps {
intialState?: number
}
export default function useCounter({intialState = 0}: CounterProps){
const [ count, setCount ] = useState(intialState);
const increment = () => setCount(pre => pre + 1);
const decrement = () => setCount(pre => pre - 1);
return({
count,
increment,
decrement
})
}
count
設定初始值為 0 是否有正確顯示。import { renderHook } from "../../test-utils";
import useCounter from "./useCounter";
describe("useCounter", () => {
test("Render initialState: 0 when no props passing", () => {
const { result } = renderHook(() => useCounter({}));
expect(result.current.count).toBe(0);
})
})
測試結果:
PASS src/hooks/useCounter/useCounter.test.tsx
renderHook
我們這幾週以來撰寫測試會使用 render()
去模擬渲染元件。但在這裡的 useCounter
並非 return JSX,因此不適用。而且,以往我們在引入自定義 Hooks 時,有個先決條件:不能在 Hooks 以外的地方進行使用。這時候,RTL 提供的 renderHook
方法就派上用場了!
renderHook
是一函式,可以接收兩參數:callBack functions
與 <options>
intialProps
或 前幾天提到的 wrapper
。useCounter
為例,我們可以這樣寫:// 寫法一:
renderHook(() => useCounter({}));
// 寫法二:
renderHook(useCounter, {
initialProps: {}
});
而 renderHook
回傳的是一物件,內容包含:
{
result: {
all: Array<any>
current: any, // useHooks 回傳的內容
error: Error
}
}
以上述的程式碼,我們使用物件解構的方式取得 result
:
const { result } = renderHook(() => useCounter({}));
import { act, renderHook } from "../../test-utils";
import useCounter from "./useCounter";
describe("useCounter", () => {
test("Render plus 1 by using increment function", () => {
const { result } = renderHook(() => useCounter({}));
act(() => result.current.increment());
expect(result.current.count).toBe(1);
console.log("🚀 result.current.count:", result.current.count)
})
test("Render minus 1 by using decrement function", () => {
const { result } = renderHook(() => useCounter({}));
act(() => result.current.decrement());
expect(result.current.count).toBe(-1);
console.log("🚀 result.current.count:", result.current.count)
})
})
測試結果:
PASS src/hooks/useCounter/useCounter.test.tsx
console.log
🚀 result.current.count: 1
console.log
🚀 result.current.count: -1
act()
act()
方法,確定 React state 已更新完成。