たかぎとねこの忘備録

プログラミングに関する忘備録を自分用に残しときます。マサカリ怖い。

@remix-run/reactからエクスポートされているコンポーネントを含んだコンポーネントをテストする場合のTips

@testing-library/reactrenderメソッドを使用してコンポーネントをテストするときに、その対象のコンポーネントが内部で@remix-run/reactパッケージから<Link />コンポーネント<Form />コンポーネントをインポートしている場合に、次のようなエラーが発生した。

...
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
The above error occurred in the <Link> component:
...
Error: useHref() may be used only in the context of a <Router> component.

テスト内でreact-router-domBrowserRouterを使ってラップしてみても解決しなかった。

しかし、色々調べていたら次のプルリクエストの内容がとても参考になった。

github.com

github.com

前提としてvitestを使用しており、vitest.config.ts内でsetupFilesを次のように設定している。

// test/setup-test-env.tsx
export default defineConfig({
  ...
  test: {
    ...
    setupFiles: ["./test/setup-test-env.tsx"],
  },
  ...
});

私の場合はsetup-test-env.tsx内で、@remix-run/reactをモックし、ファクトリ引数内でエラーの原因であると思われるコンポーネントやフックの偽バージョンを作成することによって解決することができた。

// test/setup-test-env.tsx
vi.mock("@remix-run/react", () => {
  // mock whatever remix APIs you're using
  return {
    Form: (props: any) => <form {...props} />,
    Link: (props: any) => <a {...props} />,
    useLoaderData: vi.fn(),
    useLocation: vi.fn(() => ({ key: Math.random().toString(32).slice(2) })),
  };
});

わざわざsetup-test-env.tsx内で書かなくても、各テストファイルの中で自由にモックしても良いかもしれない。