📝

複数のuseStateを用いたコンポーネントにおいて各useStateをmock化する方法【React/jest】

2023/05/21に公開

ケース

以下のような複数のuseStateを用いているコンポーネントにおいて各useStateをmock化したい。

const TestComponent = () => {
  const [A, setA] = useState("あいうえお");
  const [B, setB] = useState("かきくけこ");
  
  // 様々な処理
  
  return (
    <div>
      <span>{A}</span>
      <span>{B}</span>
    </div>
}

上記において画面にAとBの文字列が表示されているかどうか確認したい。

解決法

mockImplementationOnceを用いればよいです。これはモック関数が呼び出されたときに1回だけその値を返す関数です。メソッドチェーンを用いることで呼び出されるたびに異なる結果を返すことができます。

上記のケースだとuseStateをjest.SpyOnでモック化した後に用いることでA,Bそれぞれに値を入れることができます。(下記の例だとtesting-libraryを利用しています)

test("exmaple", () => {
  const mockSetA = jest.fn();
  const mockSetB = jest.fn();
  
  jest.spyOn(React, 'useState').mockImplementationOnce(() => ["モックあいうえお", mockSetA]) // [A, setA]をモック化
                  .mockImplementationOnce(() => ["モックかきくけこ", mockSetB]) // [B, setB]をモック化
  
  render(<TestComponent />)
  
  screen.getByText("モックあいうえお");
  screen.getByText("モックかきくけこ");
  
  // onClickなどでsetA、setBを呼び出していた場合は以下のように呼びされているかどうか確認できる
  expect(mockSetA).toHaveBeenCalled();
});

Discussion