3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React Jest】react-routerでLinkの遷移テストが成功しない場合の解決方法について

Posted at

はじめに

ReactのテストでLinkの画面遷移テストが上手くいかなかったため、解決方法について共有させていただきます。

バージョン

react v19.0.0
react-router v7.3.0
testing-library/react v16.2.0
jest v29.7.0

エラー内容

遷移できていないようです。

.tarminal
 expect(jest.fn()).toHaveBeenCalledWith(...expected)

    Expected: "/cards/register"

    Number of calls: 0

    Ignored nodes: comments, script, style

     150 |     // 新規名刺登録ページに遷移したことを期待する
      151 |     await waitFor(() => {
    > 152 |       expect(mockNavigate).toHaveBeenCalledWith("/cards/register");
          |                            ^
      153 |     });

コード内容抜粋

.spec.tsx

const mockNavigate = jest.fn();
jest.mock('react-router', () => ({
  ...jest.requireActual('react-router'), // 元のモジュール内容を展開
  useNavigate: () => mockNavigate, // useNavigate だけを上書き
}));


describe("Home Component", () => {

  it("新規登録はこちらを押すと/cards/registerに遷移する", async () => {
    render(
      <BrowserRouter>
        <Home />
        <Register />
      </BrowserRouter>
    );
   
    
    // Loading...が消えるのを待つ
    await waitFor(() =>
      expect(screen.queryByText("Loading...")).not.toBeInTheDocument()
    );
  
    // Linkを取得
    const registerLink = screen.getByRole("link", { name: "新規登録はこちら" });
   
    // Link先が正しいことを確認
    expect(registerLink).toHaveAttribute('href', '/cards/register');

    // リンクをクリック
    await userEvent.click(registerLink);

    // 新規名刺登録ページに遷移したことを期待する
    await waitFor(() => {
      expect(mockNavigate).toHaveBeenCalledWith("/cards/register");
    });
  });

});

解決方法

MemoryRouterを使用する

.spec.tsx

const mockNavigate = jest.fn();
jest.mock('react-router', () => ({
  ...jest.requireActual('react-router'), // 元のモジュール内容を展開
  useNavigate: () => mockNavigate, // useNavigate だけを上書き
}));


describe("Home Component", () => {

  it("新規登録はこちらを押すと/cards/registerに遷移する", async () => {
    
    render(
      <MemoryRouter initialEntries={['/']}>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/cards/register" element={<Register />} />
        </Routes>
      </MemoryRouter>
    )
    
    // Loading...が消えるのを待つ
    await waitFor(() =>
      expect(screen.queryByText("Loading...")).not.toBeInTheDocument()
    );
  
    // Linkを取得
    const registerLink = screen.getByRole("link", { name: "新規登録はこちら" });
   
    // Link先が正しいことを確認
    expect(registerLink).toHaveAttribute('href', '/cards/register');

    // リンクをクリック
    await userEvent.click(registerLink);

    // 新規名刺登録ページに遷移したことを期待する
    await waitFor(() => {
      expect(screen.getByTestId('register-page')).toBeInTheDocument();
    });
  });
  
});

参考

おわりに

MemoryRouter便利ですね。


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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?