目次
Jestでaxiosをmockする方法
トリガーとしてわかりやすいようにフロントも一応書いています
プロダクト側(vue)
<template>
<div>
<Button @click="axiosGetMethods">axios Get</Button>
<Button @click="axiosPostMethods">axios Post</Button>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
import axios from 'axios'
export default Vue.extend({
data(): {
result: Object
} {
return {
result: {},
}
},
methods: {
async axiosGetMethods() {
const client = axios.create({
baseURL: 'http://localhost:3000',
headers: {
'Content-Type': 'application/json',
},
responseType: 'json',
})
const response = await client.get('/get')
this.result = response
},
async axiosPostMethods() {
const client = axios.create({
baseURL: 'http://localhost:3000',
headers: {
'Content-Type': 'application/json',
},
responseType: 'json',
})
const response = await client.post('/post', 'testparam')
this.result = response
},
},
})
</script>
<style></style>
テストコード
import { shallowMount } from '@vue/test-utils'
import AxiosTestTarget from '@/pages/AxiosTestTarget.vue'
import flushPromises from 'flush-promises'
import axios from 'axios'
const createMock = axios.create({
baseURL: 'http://localhost:3000',
headers: {
'Content-Type': 'application/json',
},
responseType: 'json',
})
jest.spyOn(axios, 'create').mockReturnValue(createMock)
const axiosGetSpy = jest.spyOn(createMock, 'get')
const axiosPostSpy = jest.spyOn(createMock, 'post')
describe('axiosのapi call test', () => {
const wrapper = shallowMount(AxiosTestTarget)
beforeEach(() => {
axiosGetSpy.mockResolvedValue({ response: { testResponse: 'test' } })
axiosPostSpy.mockResolvedValue({ response: { testResponse: 'test' } })
})
it('axios get', async () => {
wrapper.findAll('Button').at(0).trigger('click')
await flushPromises()
expect(axiosGetSpy).toHaveBeenCalledWith('/get')
expect(wrapper.vm.$data.result).toEqual({
response: { testResponse: 'test' },
})
})
it('axios post', () => {
wrapper.findAll('Button').at(1).trigger('click')
expect(axiosPostSpy).toHaveBeenCalledWith('/post', 'testparam')
expect(wrapper.vm.$data.result).toEqual({
response: { testResponse: 'test' },
})
})
})
上記はaxios.createをプロダクトコード内で行いでheadersの設定をため
テスト側では実際にaxios.createしている値を使い、それをjest.spyOnで返しています。(これがないとプロダクトコード側のaxios.createが出来なくてエラー)
const createMock = axios.create({
baseURL: 'http://localhost:3000',
headers: {
'Content-Type': 'application/json',
},
responseType: 'json',
})
jest.spyOn(axios, 'create').mockReturnValue(createMock)
あとはbeforeEach側でmockで何を返すか指定してあげればOK
describe('axiosのapi call test', () => {
const wrapper = shallowMount(AxiosTestTarget)
beforeEach(() => {
axiosGetSpy.mockResolvedValue({ response: { testResponse: 'test' } })
axiosPostSpy.mockResolvedValue({ response: { testResponse: 'test' } })
})
itの中ではmethodsのaxiosGetMethodsをトリガーするボタンをクリックしてあげる処理を記載する。
また、flushPromises()がないとテスト側でawaitすることが出来ず、即データを見に行ってしまう。あとは引数とaxios.getで返ってきた値(mockした値)がdataに入っているか確認して終了。 flushPromisesは別途npm installが必要です。
https://www.npmjs.com/package/flush-promises
wrapper.findAll(‘Button’).at(0).trigger(‘click’) await flushPromises() expect(axiosGetSpy).toHaveBeenCalledWith(‘/get’) expect(wrapper.vm.$data.result).toEqual({ response: { testResponse: ‘test’ }, })axios.createってわざわざmockしたくないよね?
axios.createの外出しでaxiosの利用コードを少なくする
import axios from 'axios'
export const client = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: { 'X-Custom-Header': 'foobar' },
})
<template>
<div>
<Button @click="axiosGetMethods">axios Get</Button>
<Button @click="axiosPostMethods">axios Post</Button>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
import { client } from '@/userModules/axios.config'
export default Vue.extend({
data(): {
result: Object
} {
return {
result: {},
}
},
methods: {
async axiosGetMethods() {
const response = await client.get('/get')
this.result = response
},
async axiosPostMethods() {
const response = await client.post('/post', 'testparam')
this.result = response
},
},
})
</script>
<style></style>
import { shallowMount } from '@vue/test-utils'
import AxiosTestTarget from '@/pages/AxiosTestTarget.vue'
import flushPromises from 'flush-promises'
import { client } from '@/userModules/axios.config'
const axiosGetSpy = jest.spyOn(client, 'get')
const axiosPostSpy = jest.spyOn(client, 'post')
describe('axiosのapi call test', () => {
const wrapper = shallowMount(AxiosTestTarget)
beforeEach(() => {
axiosGetSpy.mockResolvedValue({ response: { testResponse: 'test' } })
axiosPostSpy.mockResolvedValue({ response: { testResponse: 'test' } })
})
it('axios get', async () => {
wrapper.findAll('Button').at(0).trigger('click')
await flushPromises()
expect(axiosGetSpy).toHaveBeenCalledWith('/get')
expect(wrapper.vm.$data.result).toEqual({
response: { testResponse: 'test' },
})
})
it('axios post', () => {
wrapper.findAll('Button').at(1).trigger('click')
expect(axiosPostSpy).toHaveBeenCalledWith('/post', 'testparam')
expect(wrapper.vm.$data.result).toEqual({
response: { testResponse: 'test' },
})
})
})
プロダクト側はclient.getで
テスト側はjest.spyOn(client,’get’),jest.spyOn(client,’post’)でmock出来るようになりました。
コメントを残す