Skip to content

Latest commit

 

History

History
563 lines (435 loc) · 17.9 KB

README.md

File metadata and controls

563 lines (435 loc) · 17.9 KB

🇺🇸English | 🇯🇵日本語

axios-mock-server

npm version npm bundle size CircleCI Codecov Language grade: JavaScript Dependabot Status License

axios を使った RESTful API のモックサーバー。

目次

特徴

  • GET/POST/PUT/DELETE の API エンドポイントを数行で作成できます。
  • 専用のサーバーは不要です。
  • 静的な JavaScript ファイルとして SPA でも動作します。
  • Node.js の環境でも axios をモックにすることができます。
  • Nuxt.js 同様のオートルーティング機能があり、パスの記述は必要ありません。
  • TypeScript に対応しています。

入門

インストール

  • npm を使ってインストール:

    $ npm install axios
    $ npm install axios-mock-server --save-dev
  • Yarn を使ってインストール:

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

チュートリアル

axios-mock-server の最もシンプルな使い方を紹介します。

チュートリアルを始める

API の作成

まずはモックにするファイルを保存する mocks ディレクトリを作成します。

$ mkdir mocks

次に mocks ディレクトリの中に API のエンドポイントとなるファイルを作成します。
GET リクエストでユーザーの基本情報を取得する API をモックとして定義してみましょう。

mocks/users ディレクトリを作り _userId.js ファイルを作成します。

$ mkdir mocks/users
$ touch mocks/users/_userId.js

# Windows の場合(コマンド プロンプト)
> mkdir mocks\users
> echo. > mocks\users\_userId.js

mocks/users/_userId.js のファイルには以下の記述を追加します。

// ファイル: 'mocks/users/_userId.js'
const users = [{ id: 0, name: 'foo' }, { id: 1, name: 'bar' }]

module.exports = {
  get({ values }) {
    return [200, users.find(user => user.id === values.userId)]
  }
}

axios-mock-server のルーティングは Nuxt.js のルーティングと同じように、mocks ディレクトリ内の JavaScriptTypeScript ファイルのツリー構造に合わせて自動的に生成します。

参考: Routing - Nuxt.js

つまり mocks/users/_userId.js のファイルは /users/:userId のパスとして、動的なルーティングを利用したエンドポイントを定義することができます。

API のビルド

axios-mock-server は実行前にルーティングに必要なファイルをビルドして生成する必要があります。

$ node_modules/.bin/axios-mock-server

# Windows の場合(コマンド プロンプト)
> node_modules\.bin\axios-mock-server

ビルドが成功すると $mock.js ファイルが mocks ディレクトリの中に生成されています。

$ cat mocks/\$mock.js
/* eslint-disable */
module.exports = (client) => require('axios-mock-server')([
  {
    path: '/users/_userId',
    methods: require('./users/_userId')
  }
], client)

# Windows の場合(コマンド プロンプト)
> type mocks\$mock.js

axios のモック化

最後に index.js ファイルなどで生成した mocks/$mock.js ファイルをインポートし、axios-mock-server の引数に渡せば完成です。
axios-mock-server はデフォルトで axios のすべての通信をモック化します。

// ファイル: 'index.js'
const axios = require('axios')
const mock = require('./mocks/$mock.js')

mock()

axios.get('https://example.com/users/1').then(({ data }) => {
  console.log(data)
})

index.js ファイルを実行すると { id: 1, name: 'bar' } が返ってくることがわかります。

$ node index.js
{ id: 1, name: 'bar' }

使用例

axios-mock-server は ブラウザーでの利用 から データの永続化multipart/form-data 形式の通信 までモックにすることができます。
また、Nuxt.js@nuxtjs/axios) との連携 も簡単です。

ソースコードは examples を参照してください。

使用例の一覧を見る

WIP

  • with-in-memory-database

使い方

API エンドポイントの作成

const users = [{ id: 0, name: 'foo' }, { id: 1, name: 'bar' }]

/**
 * リクエストで引数として渡される変数の型定義
 * @typedef { Object } MockMethodParams
 * @property { import('axios').AxiosRequestConfig } config axios のリクエストの設定
 * @property {{ [key: string]: string | number }} values リクエストされた URL の動的な値(パスのアンダースコア部分)
 * @property {{ [key: string]: any }} params リクエストされた URL のクエリパラメータの値
 * @property { any } data POST などで送信されたリクエストデータ
 */

/**
 * レスポンスをオブジェクトとして返す場合の型定義
 * @typedef { Object } MockResponseObject
 * @property { number } status HTTP レスポンスステータスコード
 * @property { any? } data レスポンスデータ
 * @property {{ [key: string]: any }?} headers レスポンスヘッダー
 */

/**
 * レスポンスの型定義
 * @typedef { [number, any?, { [key: string]: any }?] | MockResponseObject } MockResponse
 */

export default {
  /**
   * GET、POST などすべてのメソッドの型は共通です
   * @param { MockMethodParams }
   * @returns { MockResponse }
   */
  get({ values }) {
    return [200, users.find(user => user.id === values.userId)]
  },

  /**
   * 非同期にレスポンスを返すこともできます
   * @param { MockMethodParams }
   * @returns { Promise<MockResponse> }
   */
  async post({ data }) {
    await new Promise(resolve => setTimeout(resolve, 1000))

    users.push({
      id: users.length,
      name: data.name
    })

    return { status: 201 }
  }
}

axios との接続

デフォルト

axios-mock-server はデフォルトで axios のすべての通信をモック化します。

import axios from 'axios'
import mock from './mocks/$mock.js'

mock()

axios.get('https://example.com/api/foo').then(response => {
  /* ... */
})

特定のインスタンスのみモックにする

axios のインスタンス ごとにモック化することもできます。

import axios from 'axios'
import mock from './mocks/$mock.js'

const client = axios.create({ baseURL: 'https://example.com/api' })

mock(client)

client.get('/foo').then(response => {
  /* ... */
})

// axios はモックされません
axios.get('https://example.com/api/foo').catch(error => {
  console.log(error.response.status) // 404
})

関数

axios-mock-server ではいくつかの組み込み関数を利用することができます。

setDelayTime(millisecond: number): void

レスポンスの遅延をシミュレートします。

import axios from 'axios'
import mock from './mocks/$mock.js'

mock().setDelayTime(500)

console.time()
axios.get('https://example.com/api/foo').then(() => {
  console.timeEnd() // default: 506.590ms
})

enableLog(): voiddisableLog(): void

リクエストログの出力を切り替えます。

import axios from 'axios'
import mock from './mocks/$mock.js'

const mockServer = mock()

;(async () => {
  // 有効にする
  mockServer.enableLog()
  await axios.get('/foo', { baseURL: 'https://example.com/api', params: { bar: 'baz' } }) // 標準出力 -> [mock] get: /foo?bar=baz => 200

  // 無効にする
  mockServer.disableLog()
  await axios.get('/foo', { baseURL: 'https://example.com/api', params: { bar: 'baz' } }) // 標準出力 ->
})()

TypeScript

axios-mock-server には TypeScript の定義が含まれています。

注意事項

.gitignore

axios-mock-server がビルドで生成する $mock.js、または $mock.tsGit の監視から除外してください。

$ echo "\$mock.*" >> .gitignore

@ts-ignore, eslint-disable

TypeScript のプロジェクトの場合は、$ mock.ts をインポートする上の行に // @ ts-ignore コメントを追加します。 typescript-eslint@typescript-eslint/ban-ts-ignore ルールが有効になっている場合、ESLint から // ts-ignore コメントを除外してください。

// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore: Cannot find module
import mock from './mocks/$mock'

トラブルシューティング

TypeScript で The expected type comes from property 'get' which is declared here on type 'MockMethods' のエラー

TypeScript で非同期にレスポンスを返す場合、レスポンスを配列にしようとすると型が一致しないためにエラーになります。
MockResponse をアサーションするか、オブジェクトで返すようにしてください。

エラーになる例(axios-mock-server のビルドは通ることに注意してください!

import { MockMethods } from 'axios-mock-server'

const methods: MockMethods = {
  async get() {
    await new Promise(resolve => setTimeout(resolve, 100))
    return [200, { foo: 'bar' }] // Error
  }
}

export default methods

MockResponse をアサーションして解決します。

import { MockMethods, MockResponse } from 'axios-mock-server'

const methods: MockMethods = {
  async get() {
    await new Promise(resolve => setTimeout(resolve, 100))
    return [200, { foo: 'bar' }] as MockResponse // Type safe
  }
}

export default methods

レスポンスをオブジェクトにすることができればアサーションも不要です。

import { MockMethods } from 'axios-mock-server'

const methods: MockMethods = {
  async get() {
    await new Promise(resolve => setTimeout(resolve, 100))
    return { status: 200, data: { foo: 'bar' } } // Type safe
  }
}

export default methods

Command Line Interface のオプション

Command Line Interface では以下のオプションを指定することができます。

Option Type Default Description
--config
-c
string ".mockserverrc" 設定ファイルまでのパスを指定します。
--watch
-w
監視モードを有効にします。
API のエンドポイントとなるファイルの増減に合わせて $mock.js、または $mock.ts を再生成します。
--version
-v
axios-mock-server のバージョンを表示します。

設定

設定は .mockserverrc ファイルに JSON の構文で記述します。

Option Type Default Description
input string | string[] "mocks" or "apis" API のエンドポイントとなるファイルが保存されているディレクトリを指定します。
複数のディレクトリを指定した場合は、それぞれのディレクトリに $mock.js、または $mock.ts を生成します。
outputExt "js" | "ts" 生成するファイルの拡張子を指定します。
デフォルトは API エンドポイントのファイルの内容から自動で設定します。
outputFilename string "$mock.js" or "$mock.ts" 生成するファイル名を指定します。
target "es6" | "cjs" 生成するモジュールのコードを指定します。
デフォルトは API エンドポイントのファイルの拡張子から自動で設定します。

ライセンス

axios-mock-server は MIT License のもとで利用を許諾します。