コンポーネント内でページ遷移のテストをする方法です。
react-router-domをモック化する方法
react-router-dom自体をjestでモック化します。ただ、この方法だとwithRouterとかがコードに記述してあるコードだとうまくいきませんでした。
注意点
注意点としては実際に別コンポーネントにページ遷移をしているわけではないという点です。react-router-domのモックを用意してそれがコンポーネントのメソッドにより正常に書き換わっているかをテストするテストになります。
useHistoryをモック化する。
react-router-domの中にあるuseHistoryのpushメソッドをテスト用にダミーの関数で上書きします。
1 2 3 4 5 6 7 8 |
// ダミーの関数 const mockHistoryPush = jest.fn(); jest.mock('react-router-dom', () => ({ useHistory: () => ({ push: mockHistoryPush, // pushメソッドをダミー関数で上書きする。 }), })); |
こうすることで、テストしたいコンポーネント内でReact-router-domのuseHistory、pushメソッドを使ってページ遷移していた場合も、こちらで用意したダミーのpushメソッドを見にいくようにできます。
テストコード例(遷移前に非同期処理があるパターン)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import { render, screen, cleanup } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; 〜〜〜〜〜〜〜〜 中略 〜〜〜〜〜〜〜〜 it('ページ遷移テスト', async () => { render( <XXXコンポーネント /> ); userEvent.click(screen.getByText('遷移アクションボタン')); expect( await screen.findByText('ログイン成功時のメッセージなど') ).toBeInTheDocument(); expect(mockHistoryPush).toBeCalledWith('/遷移後のパス'); expect(mockHistoryPush).toHaveBeenCalledTimes(1); }); |
まずは、userEventを使ってページ遷移のトリガーとなるボタンを押します。
次に、もし、遷移前に非同期処理などを使っている場合は、awaitでページ遷移が成功したトリガーとなるものを記述して完了を待ちます。(もし、非同期処理がない場合はこの記述がなくても大丈夫です。)
toBeCalledWith(‘/遷移後のパス’)
mockHistoryPush(Historyのモック)が「/ログイン後のパス(例えば、/users)」というパスで呼び出されたかを判定してくれるマッチャーです。
toHaveBeenCalledTimes(呼び出された回数);
mockHistoryPush(Historyのモック)が何回呼び出されたかをチェックするマッチャーです。pushするのが1回だけなのであれば1を指定します。
用途
主に、特定のケースではpushがされないのをテストしたい場合に使います。(例えば、認証に失敗した場合はページ遷移しないので、pushしないので0を指定して呼ばれないことを確認するなど)
Routerをモック化せずそのまま使う方法
この方法であれば、withRouterで囲ってあるコンポーネント があったとしても正常に動かすことが可能でした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
describe("xxx", () => { it("yyy", () => { const history = createMemoryHistory(); history.push("遷移元のパス"); render( <Router history={history}> <コンポーネント /> </Router> ); userEvent.click(screen.getByText("ボタン")); expect(history.location.pathname).toEqual("遷移先パス"); }); }); |
この記事へのコメントはありません。