📚
【Nuxt.js】VuexのactionsをJestでテストする
Vuexのテストするポイント
- actionsでテストする内容
- 想定しているAPIのエンドポイントにアクセスしているか
- APIに渡している値が正しいか
- 想定しているmutateにコミットしているか
ソース
actions内で非同期処理をしている場合
-
it
やtest
メソッドの第2引数にasync
をつける必要がある
index.spec.ts
describe('index store', () => {
describe('actions', () => {
it('should fetchUser', async () => {
const commit = jest.fn();
const $axios
await actions.fetchUser({ commit });
});
});
});
- axiosをmockにしておく
index.spec.ts
let url = ''
let body = {}
let mockError = false
jest.mock("axios", () => ({
post: (_url, _body) => {
return new Promise((resolve) => {
if (mockError)
throw Error("Mock error")
url = _url
body = _body
resolve(true)
})
}
}))
- mockしたaxiosをstoreにセットする
- テスト対象となるstore配下のファイルをimportする
- localVueにVuexを設定する
- 1でimportしたファイルをStoreとしてオブジェクトを生成
- 3でつくったStoreにモックしたaxiosを設定する
- actionsを呼び出す際は、
dispatch(
xxx)
を使う
index.spec.ts
import { createLocalVue } from '@vue/test-utils'; // 2.でlocalVueを生成するために必要
import axios from 'axios';
import { cloneDeep } from 'lodash';
import Vuex from 'vuex';
import ROUTES from '~/routes/api';
import * as storeIndex from '~/store/index'; // 1. テスト対象となるstore配下のファイルをimportする
// axiosのmock
const localVue = createLocalVue();
localVue.use(Vuex); // 2. localVueにVuexを設定する
describe('index store', () => {
describe('actions', () => {
let store: any;
beforeEach(() => {
store = new Vuex.Store(cloneDeep(storeIndex as any)); // 3. 1でimportしたファイルをStoreとしてオブジェクトを生成
store.$axios = axios as NuxtAxiosInstance; // 4. 3でつくったStoreにモックしたaxiosを設定する
store.commit = jest.fn();
store.$router = { push: jest.fn() };
});
test('fetchUser should call user api and mutateUser', async () => {
await store.dispatch('fetchUser'); // 5. actionsを呼び出す際は、`dispatch(`xxx`)`を使う
expect(url).toBe(ROUTES.GET.USER);
store.commit('mutateUser', user);
expect(store.commit).toHaveBeenCalledWith('mutateUser', user);
});
});
});
残課題
mutateはactions内で呼び出しているので、store.commit('mutateUser', user);
をする必要はないはずですが、どうしてもmutateが呼び出されているのをどう書けばいいかがわからなかったです。。storeの_mutations
にあるのはわかったので、
expect(store._mutations.mutateUser).toHaveBeenCalledWith('mutateUser',{})
これでできないかなーとやってみたんですがうまくいかず。
「こうするんだよ」というのをご存知の方いれば教えて下さい!
参考資料
NuxtアプリケーションをJestでテストする - アクトインディ開発者ブログ
vue-testing-handbook/actions.spec.js at master · lmiller1990/vue-testing-handbook
Using with Vuex | Vue Test Utils
testing-vuex-store-example/store-config.spec.js at master · eddyerburgh/testing-vuex-store-example
Vue Testing Handbook
ディープコピーとシャローコピーの違い - ITを分かりやすく解説
Discussion