VueやJestについて
前回記事 をご参照ください。
環境
- Vue-CLI 3系をインストール済み
- 上記インストール時、UnitTestライブラリーに「Jest」、「TypeScript」を選択済み
- テスト対象のvueファイルを用意した
ディレクトリ構造
今回は、viewsのSample.vueのテストを書きたいと思います。
root/
├ src/
│ ├ api/
│ │ └ request.ts(サーバーサイドのAPIに対する、リクエストメソッドが定義されている)
│ ├ views/
│ │ └ Sample.vue(テスト対象のファイル)
│ └ store.ts(actionsが定義されている)
└ tests/
└ unit
└ Sample.spec.ts(テストを記述するファイル)
Sample.vue(テスト対象のファイル)
onClickSample()
でstore actionを呼び出します。
リクエストに成功した場合は、error
を空に、失敗した場合は何等かのエラーメッセージを格納するようになっています。
<template>
<div class="page-container">
<p class="error" v-if="error">{{error}}</p>
<button type="button" v-on:click="onClickSample">Sample Button</button>
</div>
</template>
<script lang="ts">
import { Vue } from 'vue-property-decorator';
@Component
export default class Sampleextends Vue {
private error: string = '';
private async onClickSample(): Promise<any> {
this.$store.dispatch('sample')
.then((response) => {
this.error = '';
})
.catch((error) => {
for (error of error.response.data.error_list) {
this.error = error.message;
}
});
}
}
</script>
request.ts
サーバーサイドのAPIに対する、リクエストメソッドが定義されています。/sample
へgetしていますが、このファイル内のテストは今回の対象には含んでおりません。
import axios from 'axios';
axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest';
axios.defaults.baseURL = process.env.VUE_APP_API_ENDPOINT + '/app-name';
export default {
async sample_get() {
return axios.get('/sample');
},
};
store.ts
actionsにsendメソッドを定義しています。ここからrequestファイルのpostメソッドを呼び出してAPIをリクエストしています。
import Vue from 'vue';
import Vuex from 'vuex';
import requestfrom './api/request';
Vue.use(Vuex);
export default new Vuex.Store({
actions: {
async sample({ commit }) {
const result = await request.sample_get();
return result;
},
},
});
tests/unit/Sample.spec.ts(テストを記述するファイル)
-
使用しているモジュールやライブラリーはテストファイルでも読み込む必要があります。
vueに関してそのまま使うと、グローバル Vue クラスを汚染してしまうので、createLocalVue
を使います。
https://vue-test-utils.vuejs.org/ja/api/#createlocalvue -
axiosモジュールを利用する際、実際のAPIにアクセスせずにテストをさせたいので、jestのモックを利用します。
jest.mock('axios')
の記述をすると、モックでaxiosモジュールが利用出来ます。
https://jestjs.io/docs/ja/mock-functions#%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%81%AE%E3%83%A2%E3%83%83%E3%82%AF -
beforeEachでactions、store をshallowMountする際に、モックストアとしてコンポーネントと一緒に渡す。
https://vue-test-utils.vuejs.org/ja/guides/using-with-vuex.html
// Vueをimportする代わりに、'@vue/test-utils'を使いcreateLocalVue、shallowMount をimportします
import { createLocalVue, shallowMount } from '@vue/test-utils';
// vuexをimport
import Vuex from 'vuex';
// テスト対象ファイル(@/views/Sample.vue)をimportする
import Samplefrom '@/views/Sample.vue';
// axiosをimport
import axios from 'axios';
// モジュールを自動的にモックさせる
jest.mock('axios');
const localVue = createLocalVue();
// localVueでVueXを使える様にする
localVue.use(Vuex);
describe('Sample.vue', () => {
let wrapper;
let vm;
let actions;
let store;
describe('success onClickSample', () => {
beforeEach(() => {
actions = {
sample: jest.fn(), // store.tsのsampleメソッドをスタブ
onClickSample: jest.fn(),// Sample.vueのonClickSampleをスタブ
},
store = new Vuex.Store({
state: {},
actions,
});
// SampleはSample.vueを見ている。モックストア(↑でnewしたstore)をSampleに設定してマウントしている。
wrapper = shallowMount(Sample, {
store,
localVue,
});
// Sample.vueの、ViewMountを取得している。it内でvmを使う事が出来る。
vm = wrapper.vm;
});
// errorに文言が入っている状態で、onClickSample()を実行し、リクエスト成功時にerrorが空になるかをテストしている。
// テストするメソッドがasyncを利用している場合、テスト側もasyncで書かないと動かない。
it('success: onClickSample() async/await', async () => {
vm.error= 'エラーが入っていますよ';
await vm.onClickSample();
expect(vm.error).toBe('');
});
});
});
マッチャはこちらでお探しを..
https://jestjs.io/docs/ja/expect