概要
useNavigateを使ってリンク遷移を行うReactアプリにて、useNavigateをモック化してリンク遷移テストを行います。
先月からReactとTypeScriptを使い始めたばかりなのため、指摘等ありましたらよろしくお願いします。
環境
- @types/react: 18.0.9
- @types/react-router-dom: 5.3.3
- @types/jest: 27.5.1
- react: 18.1.0
- react-router-dom: 6.3.0
- typescript: 4.6.4
やり方
まずは実装コードの紹介。
useRedirectSignUp.ts
import { useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
export type ReturnType = {
onClickSignUp: () => void;
};
// SigunUp画面への遷移
export const useRedirectSignUp = (): ReturnType => {
const navi = useNavigate();
const onClickSignUp = useCallback(() => navi('/signup'), [navi]);
return { onClickSignUp };
};
/signup
パスに遷移するonClickSignUp
関数を提供する簡素なカスタムフックです。
続いてテストコード。
useRedirectSignUp.test.ts
import { renderHook, act } from '@testing-library/react-hooks';
import { useRedirectSignUp } from '../../../hooks/SignIn/useRedirectSignUp';
// Navigatorモック準備
const mockedNavigator = jest.fn();
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useNavigate: () => mockedNavigator,
}));
describe('useRedirectSignUp', () => {
test('サインアップ画面に遷移すること', () => {
//renderHook実行
const { result } = renderHook(() => useRedirectSignUp());
// 関数実行
act(() => {
result.current.onClickSignUp();
});
// /signup を引数にNavigatorが呼び出されること
expect(mockedNavigator).toHaveBeenCalledWith('/signup');
});
});
重要なのが useNavigate
をモック化している部分です。
useNavigateは以下の形式でモック化を行います。
// Navigatorモック準備
const mockedNavigator = jest.fn();
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useNavigate: () => mockedNavigator,
}));
注意
上記Mock化コードはdescribe
の中ではなく外に記述してください。
// /signup を引数にNavigatorが呼び出されること
expect(mockedNavigator).toHaveBeenCalledWith('/signup');
後はモック化したmockedNavigator
を使って普通にテストを書いてしまってOKです。
お疲れさまでした。
参考