📒

[React]jest備忘録

2022/08/04に公開

Reactのテストの備忘録。

useState(props渡しなし)の初期設定を変更したい

useStateの初期値のままだど早期リターンされてしまう。テストで初期設定を変更して早期リターンを回避。

useFoo.tsx
import * as React from "react";
// 略
export const useFoo = () => {
  const [enable, setEnable] = React.useState(false);
  const [canExec, setCanExec] = React.useState(false);
  const [count, setCount] = React.useState(0);
  React.useEffect(() => {
  if(!enable) return; // ← 早期リターンされているのでテストがすすまない
  // 略
  }
// 略
}
useFoo.spec.ts
import { renderHook, act } from "@testing-library/react-hooks";
import { useFoo } from "./useFoo";
// 略
// 変更したいuseStateの値を設定
const mockState = {
  enable: true,
  canExec: true,
  count: 1
};

describe("Foo", () => {
 // reactをmock化
  const reactMock = require("react");
 // useStateのmock作成メソッド。mockImplementationOnceがキモ
  const setStateMockFn = jest.fn();
  const setHookState = (newState: any) => {
    return Object.keys(newState).reduce((acc, val) => {
      acc = acc?.mockImplementationOnce(() => [newState[val],setStateMockFn]);
      return acc;
    }, jest.fn());
  };
  afterEach(() => {
    jest.clearAllMocks();
  });
it("Foo test", () => {
// mockStateの値をmock化したuseStateに反映
reactMock.useState = setHookState(mockState);
const { result } = renderHook(() => useFoo());
// console.log(result.current)で 結果が確認できる

useDispatchの引数をテスト

sample.tsx
import * as React from "react";
import { useDispatch } from "react-redux";
// 略
export const Sample: React.FC = () => {
  const dispatch = useDispatch();
  useEffect(() => {
   dispatch(someAction(2))
  }, [])
sample.spec.ts
import * as redux from "react-redux";

describe("test", () => {
 const useDispatchSpy = jest.spyOn(redux, 'useDispatch');
 const mockDispatchFn = jest.fn();
  useDispatchSpy.mockReturnValue(mockDispatchFn);
  afterEach(() => {
   useDispatchSpy.mockClear();
  });
it("test", () => {
/*
console.log(mockDispatchFn.mock.calls)でdispathの中身が確認できる。
タイプとペイロードを持つオブジェクトが2重配列の中にある。
`dispatch(someAction(2))`が2回実行されるとオブジェクトの入った配列が増えていく
[
 [{ type: 'AnyActionName', payload: 'AnyvValue' }], // ここが増える
]
中身が確認できたのであとはテストしたい項目を記述していく。
*/
   expect(mockDispatchFn.mock.calls[0][0].payload).toBe(2);

// 略

このあとも追記していきます

Discussion