Vuexでstoreのモジュールをファイル分割したときのaxios-mock-adapter

# はじめに
vueで開発しているプロジェクトがなかなか大きくなりそうなので、
storeのモジュールを機能ごとにファイルで分割しました。

開発中は[axios-mock-adapter](https://github.com/ctimmerm/axios-mock-adapter)を使ってAPI通信の実装をしていたのですが、
storeモジュールを分割してからmockの挙動がおかしくなりハマりました。
いろいろ書き方を模索したら解決したので、その記録です。

VueとVuexをある程度理解している方向けに書いてます。

最終的なソースコードは[こちら (github)](https://github.com/bakupen/test-axios-mock)

# 環境
書いた日: 2019/10/25

* node v10.16.0
* npm v6.10.2
* vue-cli 3

# 作るもの

これ

![qiita.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408585/1aff55a8-53a5-dfb7-7af9-eb71468e8ca8.gif)

# ファイル構成
「ユーザ情報取得」「ユーザ一覧取得」という異なる機能のモジュールを、ファイルで分割

```
src/
├── App.vue
├── main.js
├── router
│   └── index.js
├── store
│   ├── getDetail.js  # ユーザ情報を取得するモジュール
│   ├── getList.js    # ユーザ一覧を取得するモジュール
│   └── index.js
└── views
    └── Home.vue
```


# やりたいこと

このようなファイル構成の時に、getList.jsでもgetDetail.jsでもaxiosをモックしたい

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408585/79afdb4e-9eab-dced-b3c0-848971d0a10b.png)

# ダメだった書き方

#### それぞれのモジュールファイルにmockを作成し、

```store/getList.js
import axios from 'axios'
import MockAdapter from 'axios-mock-adapter'

// mock start
const mock = new MockAdapter(axios)

mock.onGet('/users').reply(200, {
  userlist: [
    {
      id: 1,
      name: 'ほげ森ほげ太郎',
      age: 24
    },
    {
      id: 2,
      name: 'ほげ田ほげ美',
      age: 31
    },

・・・ 中略 ・・・

  ]
})
// mock end

export const state = {
  list: ''
}

export const mutations = {
  addList(state, payload) {
    state.list = payload
  }
}

export const actions = {
  getList({ commit }) {
    axios.get('/users')
    .then((response) => {
      commit('addList', response.data.userlist)
    })
    .catch((reject) => {
      console.log(`getList: ${reject.message}`)
    })
  }
}

・
・
```

```store/getDetail.js
import axios from 'axios'
import MockAdapter from 'axios-mock-adapter'

// mock start
const mock = new MockAdapter(axios)

mock.onGet('/users/1').reply(200, {
  userdetail: [
    {
      id: 1,
      name: 'ほげ森ほげ太郎',
      age: 24
    }
  ]
})

mock.onGet('/users/2').reply(200, {
  userdetail: [
    {
      id: 2,
      name: 'ほげ田ほげ美',
      age: 31
    }
  ]
})

・・・ 中略 ・・・

// mock end

export const state = {
  detail: ''
}

export const mutations = {
  addDetail(state, payload) {
    state.detail = payload
  }
}

export const actions = {
  getDetail({ commit }, id) {
    axios.get(`/users/${id}`)
    .then((response) => {
      commit('addDetail', response.detail.userdetail)
    })
    .catch((reject) => {
      console.log(`getDetail: ${reject.message}`)
    })
  }
}

・
・
```

#### indexで読み込み

```store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'

// モジュールのインポート
import getList from '@/store/getList.js'
import getDetail from '@/store/getDetail.js'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    getList,
    getDetail
  },
  plugins: [createPersistedState({storage: window.sessionStorage})]
})
```

### わかったこと

* `store/getList.js` の `axios.get` が失敗し、404エラーが返ってきた
 * → `store/index.js` で最後にインポートしたモジュールだけ、mockが有効化されるらしい

```
// モジュールのインポート
import getList from '@/store/getList.js'       # 動かない
import getDetail from '@/store/getDetail.js'   # こっちは動く
```

# 動いた書き方

mockをそれぞれのモジュールファイルに書くのではなく、
すべてのmockをindexにまとめて書く

```store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'

import axios from 'axios'                       // 追加
import MockAdapter from 'axios-mock-adapter'    // 追加

// モジュールのインポート
import getList from '@/store/getList.js'
import getDetail from '@/store/getDetail.js'

// mock start                                   // 追加↓

const mock = new MockAdapter(axios)

// getList
mock.onGet('/users').reply(200, {
  userlist: [
    {
      id: 1,
      name: 'ほげ森ほげ太郎',
      age: 24
    },
    {
      id: 2,
      name: 'ほげ田ほげ美',
      age: 31
    },

・・・ 中略 ・・・

  ]
})

// getDetail
mock.onGet('/users/1').reply(200, {
  userdetail: [
    {
      id: 1,
      name: 'ほげ森ほげ太郎',
      age: 24
    }
  ]
})

mock.onGet('/users/2').reply(200, {
  userdetail: [
    {
      id: 2,
      name: 'ほげ田ほげ美',
      age: 31
    }
  ]
})

・・・ 中略 ・・・

// mock end                                   // 追加↑

Vue.use(Vuex)

export default new Vuex.Store({
・
・
```