
Web開発ソフトウェアテスト徹底攻略 (React Hooks/Redux + Django REST API) @udemy
▼コンポーネントイメージ

Web開発ソフトウェアテスト徹底攻略 (React Hooks/Redux + Django REST API) @udemy
作成したテスト用ファイルに以下をインポートする
/** 外部import */
import React from "react";
import { render, screen, cleanup } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { rest } from "msw";
import { setupServer } from "msw/node";
import { Provider } from "react-redux";
import { configureStore } from "@reduxjs/toolkit";
/** 内部import */
// authSlice.reducerをauthReducerという名でimport
import authReducer from "../features/authSlice";
// vehicleSlice.reducerをvehicleReducerという名でimport
import vehicleReducer from "../features/vehicleSlice";
// testを行うコンポーネント
import { MainPage } from "../components/MainPage";
userEvent:ユーザーによるボタンクリックやタイピングといった動作をシミュレーションするためのもの
rest:APIをモッキングするモジュール(REST API専用はrest)
<aside> 🌿 【モッキング】
テストのスピードと信頼性を高めるために、実際の外部サービスや内部サービスの代わりをする、偽のサービスを作成すること。
実装をテストするときに、オブジェクトの関数や振る舞いではなくプロパティが必要となる場合、モックを使用できる。
</aside>
setupServer:サーバーをセットアップする
Provider, configureStore:今回はreduxのstoreを動かしながらインテグレーションテスト(結合テスト)を行うため、これらも必要
本件のMainPageコンポーネントでは、react-router-domのuseNavigateを使って、ログアウト後のページ遷移を実装していたので、そのモック関数を作成する
作成したテスト用ファイルに、jestの関数を使ってmockedNavigatorを作成する
/** 外部import */
import React from "react";
import { render, screen, cleanup } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { rest } from "msw";
import { setupServer } from "msw/node";
import { Provider } from "react-redux";
import { configureStore } from "@reduxjs/toolkit";
/** 内部import */
// authSlice.reducerをauthReducerという名でimport
import authReducer from "../features/authSlice";
// vehicleSlice.reducerをvehicleReducerという名でimport
import vehicleReducer from "../features/vehicleSlice";
// testを行うコンポーネント
import { MainPage } from "../components/MainPage";
// react-routerのuseNavigateのモック関数
**const mockedNavigator = jest.fn();**
jest.fn()はダミーの関数なので、実際には何の処理も走らないが、mockedNavigatorメソッドが呼び出されているか否かをテストできる続けて、MainPageコンポーネント内に記述したreact-router-domのuseNavigate によるページ遷移先を上書きする
〜〜〜
// react-routerのuseNavigateのモック関数
const mockedNavigator = jest.fn();
// MainPageコンポーネント内のuseNavigateによるページ遷移先を上書き
**jest.mock("react-router-dom", () => ({
...jest.requireActual('react-router-dom'),
useNavigate: () => mockedNavigator,
}));**
▼jest.requireActual(moduleName)
モックの作成完了!
本件のMainPageコンポーネントでは、以下2種のエンドポイントにアクセスしている
認証成功した(ログインした)ユーザー情報を取得するエンドポイント
MainPageコンポーネント内に設置している以下コンポーネント内では、それぞれ情報を取得するよう処理を走らせているため、それらのエンドポイント
<aside> 🌿 MainPageコンポーネントがレンダリングされた時点で、その中に設置していた各コンポーネントもレンダリングされるため、各コンポーネントでCRUD操作を有する処理を走らせていた場合は、それらのエンドポイントのモックをMainPageのテストファイルでも用意する必要があるよ!
コンポーネントを設置していた場合は、基本的にuseEffect()があるかどうか、あった場合その中でAPIにアクセスする処理を書いていないかをみておこう!
書いてあったらそのエンドポイントのモックを作成するイメージだよ!
</aside>
これらをモックしたエンドポイントを作成する
作成したテスト用ファイルに、以下のようなモックしたエンドポイントを作成する
〜〜〜
// MainPageコンポーネント内のuseNavigateによるページ遷移先を上書き
****jest.mock("react-router-dom", () => ({
...jest.requireActual('react-router-dom'),
useNavigate: () => mockedNavigator,
}));
// mswを使った、擬似的なAPIのエンドポイントの作成
**const handlers = [
rest.get("<http://localhost:8000/api/profile/>", (req, res, ctx) => {
return res(ctx.status(200), ctx.json({ id: 1, username: "test user" }));
}),
// segmentコンポーネント内で使うエンドポイント(segments一覧情報の取得)
// jsonは空の配列を返すように設定
rest.get("<http://localhost:8000/api/segments/>", (req, res, ctx) => {
return res(ctx.status(200), ctx.json([]));
}),
// brandsコンポーネント内で使うエンドポイント(brands一覧情報の取得)
rest.get("<http://localhost:8000/api/brands/>", (req, res, ctx) => {
return res(ctx.status(200), ctx.json([]));
}),
// vehiclesコンポーネント内で使うエンドポイント(vehicles一覧情報の取得)
rest.get("<http://localhost:8000/api/vehicles/>", (req, res, ctx) => {
return res(ctx.status(200), ctx.json([]));
}),
];**