こんにちは。
Next.js上でuseRouter
で遷移先を設定した箇所のテストコードを書く際に詰まってしまったため、備忘録の意味をこめて原因と対策を書いていこうと思います。
ボタン側のコンポーネント構成
下記のようにrouter.push()
を設定することで/home/ディレクトリに遷移できるようなボタンです。
Button.tsx
"use client";
import { useRouter } from "next/navigation";
import React from "react";
const MoveButton = () => {
const router = useRouter();
const onClickArticle = (e) => {
e.preventDefault;
router.push("/home/");
};
return (
<button onClick={onClickArticle} >
もっと見る
</button>
);
};
export default MoveButton;
テストを正しく実行させる方法
useRouter内のpush()の指定方法
前提として、useRouter
のような外部モジュールを使用する部分のテストを書くためにはモック化をする必要があります。
その際に、router.push()
のようにメソッドで登録されている関数をモック化する場合はモック化する関数もメソッドの形式(=オブジェクトの中にpushプロパティを書く)必要がありました。
const mockedRouter = jest.fn();
// push()メソッドはuseRouterオブジェクト内の値のため、
// pushはオブジェクトの内側に書く必要がある
jest.mock("next/navigation", () => ({
useRouter: () => ({
push: mockedRouter,
}),
}));
遷移先のモック化方法
遷移先の設定はusePathname
関数を使い、モック化する遷移先をmockReturnValue()
で設定してあげることで解決しました。
jest.mock("next/navigation", () => ({
usePathname: jest.fn().mockReturnValue("/blogs/"),
}));
完成系サンプル
sample.spec.tsx
const mockedRouter = jest.fn();
jest.mock("next/navigation", () => ({
useRouter: () => ({
push: mockedRouter,
}),
usePathname: jest.fn().mockReturnValue("/blogs/"),
}));
まとめ
useRouter(router.push()
)のようにメソッドになっている関数のモック化に関しては、本来の構造と同じくオブジェクトの内側にモックしたいプロパティを書くことで対応できました。
同じように詰まっている人の助けになれば幸いです。
参考資料