
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 */
// vehicleSlice.reducerをvehicleReducerという名でimport
import vehicleReducer from "../features/vehicleSlice";
// testを行うコンポーネント
import { Brand } from "../components/Brand";
userEvent:ユーザーによるボタンクリックやタイピングといった動作をシミュレーションするためのもの
rest:APIをモッキングするモジュール(REST API専用はrest)
<aside> 🌿 【モッキング】
テストのスピードと信頼性を高めるために、実際の外部サービスや内部サービスの代わりをする、偽のサービスを作成すること。
実装をテストするときに、オブジェクトの関数や振る舞いではなくプロパティが必要となる場合、モックを使用できる。
</aside>
setupServer:サーバーをセットアップする
Provider, configureStore:今回はreduxのstoreを動かしながらインテグレーションテスト(結合テスト)を行うため、これらも必要
本件のBrandコンポーネントでは、以下2種のエンドポイントにアクセスしている
これらをモックしたエンドポイントを作成する
作成したテスト用ファイルに、以下のようなモックしたエンドポイントを作成する
〜〜〜
// mswを使った、擬似的なAPIのエンドポイントの作成
**const handlers = [
// 一覧取得
rest.get("<http://localhost:8000/api/brands/>", (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json([
{ id: 1, brand_name: "Toyota" },
{ id: 2, brand_name: "Tesla" },
])
);
}),
// 新規作成
rest.post("<http://localhost:8000/api/brands/>", (req, res, ctx) => {
return res(ctx.status(201), ctx.json({ id: 3, brand_name: "Audi" }));
}),
// 更新
rest.put("<http://localhost:8000/api/brands/1/>", (req, res, ctx) => {
return res(ctx.status(200), ctx.json({ id: 1, brand_name: "new Toyota" }));
}),
rest.put("<http://localhost:8000/api/brands/2/>", (req, res, ctx) => {
return res(ctx.status(200), ctx.json({ id: 2, brand_name: "new Tesla" }));
}),
// 削除
rest.delete("<http://localhost:8000/api/brands/1/>", (req, res, ctx) => {
return res(ctx.status(200));
}),
rest.delete("<http://localhost:8000/api/brands/2/>", (req, res, ctx) => {
return res(ctx.status(200));
}),
];**
続けて、handlers を使ってサーバーを作成する
〜〜〜
// mswを使った、擬似的なAPIのエンドポイントの作成
const handlers = [
// 一覧取得
rest.get("<http://localhost:8000/api/brands/>", (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json([
{ id: 1, brand_name: "Toyota" },
{ id: 2, brand_name: "Tesla" },
])
);
}),
// 新規作成
rest.post("<http://localhost:8000/api/brands/>", (req, res, ctx) => {
return res(ctx.status(201), ctx.json({ id: 3, brand_name: "Audi" }));
}),
// 更新
rest.put("<http://localhost:8000/api/brands/1/>", (req, res, ctx) => {
return res(ctx.status(200), ctx.json({ id: 1, brand_name: "new Toyota" }));
}),
rest.put("<http://localhost:8000/api/brands/2/>", (req, res, ctx) => {
return res(ctx.status(200), ctx.json({ id: 2, brand_name: "new Tesla" }));
}),
// 削除
rest.delete("<http://localhost:8000/api/brands/1/>", (req, res, ctx) => {
return res(ctx.status(200));
}),
rest.delete("<http://localhost:8000/api/brands/2/>", (req, res, ctx) => {
return res(ctx.status(200));
}),
];
// サーバーの作成(mock server walkerの作成)
// エンドポイントが複数あるため、...で展開している
**const server = setupServer(...handlers);**
作成したテスト用ファイルに、以下のようなテスティング(テストケース)の設定を記述する
〜〜〜
// サーバーの作成(mock server walkerの作成)
// エンドポイントが複数あるため、...で展開している
const server = setupServer(...handlers);
// テスティングの設定
**beforeAll(() => {
server.listen();
});
afterEach(() => {
server.resetHandlers();
cleanup();
});
afterAll(() => {
server.close();
});**
1つのテストファイルには、複数のテストケースを書くことができる
breforeAll() :テストの塊の一番最初に、1回だけ実行される。
afterAll() :全てのテストケースが終了した後に、1回だけ実行される。
afterEach() :各テストケースが終わった時に、毎回呼び出される。