Web開発ソフトウェアテスト徹底攻略 (React Hooks/Redux + Django REST API) @udemy

Web開発ソフトウェアテスト徹底攻略 (React Hooks/Redux + Django REST API) @udemy

▼コンポーネントイメージ

Web開発ソフトウェアテスト徹底攻略 (React Hooks/Redux + Django REST API) @udemy

Web開発ソフトウェアテスト徹底攻略 (React Hooks/Redux + Django REST API) @udemy

準備

1. 必要ライブラリ・モジュールのインポート

  1. 作成したテスト用ファイルに以下をインポートする

    /** 外部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";
    

2. 擬似的なAPIのエンドポイントの作成(msw使用)& サーバーの作成

本件のBrandコンポーネントでは、以下2種のエンドポイントにアクセスしている

これらをモックしたエンドポイントを作成する

  1. 作成したテスト用ファイルに、以下のようなモックしたエンドポイントを作成する

    〜〜〜
    
    // 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));
      }),
    ];**
    
  2. 続けて、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);**
    

3. テスティング(テストケース)の設定

  1. 作成したテスト用ファイルに、以下のようなテスティング(テストケース)の設定を記述する

    〜〜〜
    
    // サーバーの作成(mock server walkerの作成)
    // エンドポイントが複数あるため、...で展開している
    const server = setupServer(...handlers);
    
    // テスティングの設定
    **beforeAll(() => {
      server.listen();
    });
    afterEach(() => {
      server.resetHandlers();
      cleanup();
    });
    afterAll(() => {
      server.close();
    });**
    

    1つのテストファイルには、複数のテストケースを書くことができる

4. describeの作成・下準備(名前付け・テスト用storeの作成)