4
2

More than 1 year has passed since last update.

【jest】モック化したuseRecoilValueの戻り値がundefinedになる【react】

Posted at

はじめに

タイトルどおりですが、モック化したuseRecoilValueuseRecoilStateの戻り値がundefinedになってしまう現象に遭遇し、小一時間ハマってしまいました。
jest 初心者なので勉強がてらメモを残します。

解決策

後に再現コードを記載しますが、先に結果を知りたい人用に解決策を記載します。
結論としては、以下の 2 点が解決策となります。

  • 各テストケースごとにmockImplementationを書く
  • beforeEachmockImplementationを書く

beforeEachと似た関数にbeforeAllがありますが、こちらはうまく動作しませんでした。
公式ドキュメント:beforeAll(fn, timeout)beforeEach(fn, timeout)

再現コード

テスト対象のコンポーネントは成功、失敗に関わらず同一です。

テスト対象
import { atom, useRecoilValue } from "recoil";

const store = atom({
  key: "store",
  default: "default value",
});

function App() {
  const state = useRecoilValue(store);

  return (
    <div>
      <p id="test-element-1">{state}</p>
    </div>
  );
}

export default App;

うまくいったケース

テストコード
import { useRecoilValue } from "recoil";
import { shallow } from "enzyme";
import App from "./App";

jest.mock("recoil");

describe("各テストケースごとに mockImplementation を書く", () => {
  test("recoilテスト", () => {
    useRecoilValue.mockImplementation(() => "test value");

    const result = shallow(<App />);
    expect(result.find("#test-element-1").text()).toEqual("test value");
  });
});

describe("beforeEach に mockImplementation を書く", () => {
  beforeEach(() => {
    useRecoilValue.mockImplementation(() => "test value");
  });

  test("recoilテスト", () => {
    const result = shallow(<App />);
    expect(result.find("#test-element-1").text()).toEqual("test value");
  });
});

うまくいかなかったケース

いずれもstateの中身がundefinedになっています。

ケース① - jest.mockuseRecoilValueをモック化する

テストコード
import { shallow } from "enzyme";
import App from "./App";

jest.mock("recoil", () => ({
  ...jest.requireActual("recoil"),
  useRecoilValue: jest.fn(() => "test value"),
}));

describe("jest.mock で useRecoilValue をモック化する", () => {
  test("recoilテスト", () => {
    const result = shallow(<App />);
    expect(result.find("#test-element-1").text()).toEqual("test value");
  });
});

ケース② - beforeAllmockImplementationを書く

テストコード
import { useRecoilValue } from "recoil";
import { shallow } from "enzyme";
import App from "./App";

jest.mock("recoil");

describe("beforeAll に mockImplementation を書く", () => {
  beforeAll(() => {
    useRecoilValue.mockImplementation(() => "test value");
  });

  test("recoilテスト", () => {
    const result = shallow(<App />);
    expect(result.find("#test-element-1").text()).toEqual("test value");
  });
});
4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2