3
0

More than 1 year has passed since last update.

Remixでコンポーネントをテストしたときに直面した面倒なエラー

Posted at

Remixを使って開発しているプロジェクトにて、@remix-run/reactから公開されている<Form />を内部で使用しているコンポーネントをテストしようとしました。

Item.tsx
import { Form } from "@remix-run/react";

export function Item() {
  return (
    <div>
      <Form method="post">
        <input type="hidden" name="id" value={id} />
        ...
        <button type="submit" />
      </Form>
    </div>
  );
}

これをvitest@testing-library/reactを使ってテストしようとしたところ、次のようなエラーが発生しました。

The above error occurred in the <FormImpl> component:
...
Error: useNavigate() may be used only in the context of a <Router> component.

この<Item />コンポーネントでは直接useNavigate()は呼び出していませんが、おそらく<Form />の内部で呼び出しているために、このようなエラーが発生するのだと推測されます。

これを回避するために、<BrowserRouter />でラップすれば良いと思うかもしれませんが、そう簡単にはいきません。

もし仮に<BrowserRouter />でラップしてみてもError: You must render this element in a remix route elementというエラーが発生します。

なので、ここは大人しくVitestの機能を使ってモックを行うことにします。

vitest.config.tsにてtest.setupFilesにセットアップファイルのパスを設定します。

vitest.config.ts
/// <reference types="vitest" />
/// <reference types="vite/client" />
...
export default defineConfig({
  ...
  test: {
    ...
    setupFiles: ["./test/setup-test-env.ts"],
    ...
  },
});

指定したセットアップファイルにて、@remix-run/reactから公開されているuseNavigate()<Form />をモックします。

setup-test-env.ts
import { installGlobals } from "@remix-run/node";
// import { useNavigate } from "@remix-run/react";
import "@testing-library/jest-dom/extend-expect";
import type React from "react";

installGlobals();

vi.mock("@remix-run/react", () => {
  const useNavigate = vi.fn();
  const form = vi.fn().mockImplementation(({ children }: { children: React.ReactElement, }) => {
    return children
  });
  return {
    useNavigate,
    Form: form,
  }
})

特徴としては、このセットアップファイルはtsxではないので、<Form />をモックするときはchildrenを引数に取る関数を渡す必要があります。そしてその関数の中でchildrenを返すようにします。

もう一度テストをしてみたところ、無事にテストが通りました。

Test Files  1 passed (1)
     Tests  1 passed (1)
  Start at  13:05:23
  Duration  2.33s (transform 631ms, setup 669ms, collect 458ms, tests 14ms)


PASS  Waiting for file changes...

あまり同じようなエラーに遭遇した人がいないためか、これの問題に正面から解説されている記事がありませんでした。

僕が費やした数時間が、誰かの助けにでもなれば幸いです。

参照記事

3
0
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
3
0