👻
Nuxt.jsとJestで非同期通信の結果を表示するalertのテストをする
Nuxt.jsでコンポーネントの単体テストを作成していて、以下2つをテストをしたい。
- axiosで処理を投げる
- 上記のレスポンスから取得した内容を
alert
で表示する
環境
- Vue.js 2.6.12
- Nuxt.js 2.14.12
- Jest 26.6.3
- @nuxtjs/axios 5.12.5
- @vue/test-utils 1.1.2
- vue-jest 3.0.7
前提
テスト対象コンポーネント
仕様
ボタンを押すとAPI通信をして、レスポンスからname
を取得しalert
で表示する
※JSONPlaceholderを利用
想定レスポンス
- エンドポイント :
GET /users/1
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere@april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
}
コンポーネント
GetUserButton.vue
<template>
<button @click="getUser">ボタン</button>
</template>
<script lang="js">
import Vue from 'vue'
const url = 'https://jsonplaceholder.typicode.com/users/1';
export default Vue.extend({
name: 'DoSomethingButtuon',
methods: {
async getUser(){
const user = await this.$axios.$get(url);
alert(user.name);
}
}
})
</script>
テストコード
テスト項目
- 想定したAPIのエンドポイントにアクセスしていること
- ボタンをクリックしたときに、APIから返ってきた結果を
alert
に表示できていること
テストコード全体
GetUserButton.spec.js
import GetUserButton from '@/components/GetUserButton.vue';
import { mount } from '@vue/test-utils';
let wrapper;
beforeAll(() => {
wrapper = mount(GetUserButton, {
// mocksプロパティにaxiosのモックを設定
mocks: {
$axios: {
$get: jest.fn(() => Promise.resolve({ name: 'test user' }))
}
}
})
// window.alertをモックにする。Jestではモックにしないとエラーになる
window.alert = jest.fn()
})
describe('GetUserButton', () => {
// テストメソッドの第2引数にasyncをつける
it('should access the appropriate endpoints', async () => {
// 非同期処理なので、awaitをつける
await wrapper.find('button').trigger('click');
expect(wrapper.vm.$axios.$get).toHaveBeenCalledWith(
'https://jsonplaceholder.typicode.com/users/1'
)
})
it('should display alerts with user name', async () => {
await wrapper.find('button').trigger('click');
expect(window.alert).toHaveBeenCalledWith('test user');
})
})
mocks プロパティに axios のモックを設定
通常実行時はNuxtがaxiosをいい感じにしてくれますが、Jestでは自分で設定する必要があります。
テストで共通に使うのでbeforeAll
を使って、テスト対象のコンポーネントを準備しています。
GetUserButton.spec.js
let wrapper;
beforeAll(() => {
wrapper = mount(GetUserButton, {
// mocksプロパティにaxiosのモックを設定
mocks: {
$axios: {
$get: jest.fn(() => Promise.resolve({ name: 'test user' }))
}
}
})
})
window.alert にモックを設定
上記と同じように、window.alert
もモックにしてあげます。
GetUserButton.spec.js
beforeAll(() => {
...
// window.alertをモックにする。Jestではモックにしないとエラーになる
window.alert = jest.fn()
})
trigger 部分は await をつける(合わせて it の第 2 引数に async)
テスト対象内では非同期通信をしているため、テストメソッドもそれに合わせてawait/asyncをつけます。
GetUserButton.spec.js
describe('GetUserButton', () => {
// テストメソッドの第2引数にasyncをつける
it('should access the appropriate endpoints', async () => {
// 非同期処理なので、awaitをつける
await wrapper.find('button').trigger('click');
expect(wrapper.vm.$axios.$get).toHaveBeenCalledWith(
'https://jsonplaceholder.typicode.com/users/1'
)
})
...
})
Discussion