28
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

axios をモックする方法 (React + TypeScript)

Last updated at Posted at 2020-12-05

はじめに

HTTPクライアントでお馴染みの axios のモック化を試したかったので、
それに関しての導入記事となります。

モックに関しては、 axios-mock-server を利用します。

フロントは、 React + TypeScript でサンプルを記述します。

環境

  • macOS Catalina 10.15.6
  • node: v15.3.0
  • yarn: 1.22.10
  • TypeScript: 4.1.2
  • React: 17.0.0
  • axios-mock-server: 0.19.0

1. パッケージの導入

$ yarn add axios
$ yarn add --dev axios-mock-server

npm じゃなくて yarn を利用しています。

2. axios を利用した HTTPクライアント の作成

axios を利用した形の HTTPクライアント部分を実装します。
とりあえず最低限の get/post のみです。

src/data/rest.ts
import axios from "axios";

type Data = { [key: string]: string | number | boolean | object }

const rest = (() => {
  const client = axios.create({
    baseURL: '', // 今回は未指定 (通常は env などから参照させる)
    timeout: 15000,
  });
  return {
    client,
    get: <T = any, R = AxiosResponse<T>>(url: string): Promise<R> => {
      return client.get(url);
    },
    post: <T = any, R = AxiosResponse<T>>(url: string, data: Data): Promise<R> => {
      return client.post(url, data);
    }
})();

export { rest };

この時点ではまだモックを考慮していません。
また、本サンプルでは POST は未使用ですが一応定義しておきます。

3. API のインターフェースを定義

今回仮に User一覧 を返すAPIを想定します。
一旦クエリパラメータは無しで。

Method URL
GET http://localhost:3000/user/list

レスポンスの型定義

src/data/type/index.ts
type User = {
  id: number;
  name: string;
}

export type { User };

APIの実装部分

src/data/api/getUsers.ts
import { rest } from '../rest';
import { User } from '../type';

const getUsers = async (): Promise<User[]> => {
  const url = "/user/list";
  try {
    const { data } = await rest.get<User[]>(url)
    return data;
  } catch (error) {
    throw new Error(error);
  }
}

export { getUsers };

コンポーネント側から呼び出す場合はこんな感じです。

src/component/Users.tsx
import React, { useEffect } from 'react';
import { getUsers } from '../data';

const Users: React.FC = () => {
  useEffect(() => {
    getUsers().then((users) => {
      console.log('# users', users);
    });
  }, []);
  return <span>Users</span>;
};

export { Users };

4. mockserverrc の作成

プロジェクトのルート階層(package.jsonがある場所)に .mockserverrc を作成します。
今回 モックAPI のファイルとして、
/src/data/mock に格納したいので、そこのパスを指定しています。

.mockserverrc
{
  "input": "./src/data/mock"
}

5. モックAPI の作成

モックAPIを格納するディレクトリは以下の通りです。
(見ての通りディレクトリ構造に沿って、自動的にルーティングが設定されます)

├── data
│   └── mock
│       ├── $mock.ts  ... ※自動生成されるファイル (後述で説明)
│       └── user
│           └── list.ts

User一覧のモックAPIの実装です。

src/data/mock/user/list.ts
import { MockMethods, MockResponse } from 'axios-mock-server';
import { User } from '../../type';

const list: MockMethods = {
  get: async (): Promise<MockResponse> => {
    const data: User[] = [
      {
        id: 1,
        name: 'A'
      },
      {
        id: 2,
        name: 'B'
      }
    ];
    return [200, data]; // 200 はステータスコード
  }
};

export default list; // ここは `default export` にしないと動かない

6. モックAPIをビルドするスクリプトを定義

package.json の scripts にモックAPIのビルド設定を追記します。
-c で 設定ファイルを指定しています。

package.json
  ...
  "scripts": {
    ...
    "mock:build": "axios-mock-server -c .mockserverrc"
  },

7. モックAPIのビルド

以下のコマンドを実行します。

$ yarn mock:build

$mock.ts が自動生成されていればOKです。
生成されたコードは以下の通りです。
自動生成されたファイルは、適宜.gitignoreに追加してください。

data/mock/$mock.ts
/* eslint-disable */
import { AxiosInstance } from 'axios'
import mockServer from 'axios-mock-server'
import mock0 from './user/list'

export default (client?: AxiosInstance) => mockServer([
  {
    path: '/user/list',
    methods: mock0
  }
], client, '')

8. axios とモックの紐付け

手順 2. で生成した HTTPクライアント に修正を加えます。
自動生成した mock モジュールを import し、
関数呼び出しの引数に axios の client を渡しております。

また、お好みで ログ出力 や 遅延設定 は行なえます。

src/data/rest.ts
import axios, { AxiosResponse } from "axios";
+ import { mock } from './mock';

  ... 省略 ...

+ const useMock = true;
+ if (useMock) {
+   mock(rest.client)
+     .enableLog()
+     .setDelayTime(500);
+ }

export { rest };

9. 起動コマンドの追加 及び 動作確認

このままだとモックAPIを改修する度に、
mock:buildコマンドを実行しないといけないので、
独自の起動コマンドを追加します。

package.json の scripts に以下を追加します。

package.json
  ...
  "scripts": {
    ...
    "mock:build": "axios-mock-server -c .mockserverrc"
+   "mock:start": "axios-mock-server -c .mockserverrc && react-scripts start"
  },

react-scripts startyarn start で実行するコマンド内容です。

ローカルでの実行は以下のコマンドとなります。

$ yarn mock:start

enableLog()を有効にしていると、API呼び出し時にログが出力されます。
スクリーンショット 2020-12-04 16.51.51.png

まとめ

以上、axios をモックする方法となります。
サンプルコードは以下にアップしています。
https://github.com/unpii/react-axios-mock-example

28
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?