Jest for Vue 發送 API 用 axios
Jest for Vue 發送 API 用 axios
承 Jest for Vue with Vuex 實戰 的進度。
這次,希望可以測試 axios 得到的 JSON 是不是可以跑到畫面來。
這次的練習,會利用無跨域 API 來練習
測試 GET
本質上,是要測試 axios.get('url').then(res => res.data)
這一段裡的 res
值回傳內容,是不是和 API 文件裡的一致,並且是不是會到畫面正確的位置上。
Components
Actions.vue
增加了一個 button 讓最後得到的 JSON 放在 Vuex 裡。
再透過 getters 放在 <pre>
裡。
1 2 3 4 5 6 7 8
| <template> <div class="text-align-center"> ... <button id="getJson" @click="$store.dispatch('fetchCoscup')">Get COSCUP</button> <pre>{{ $store.getters.json }}</pre> ... </div> </template>
|
畫面呈現 (下面畫面包含已回傳的 JSON)
Json Schema
利用 Json Schema 比對 JSON 結果
記得安裝
$ npm install --save-dev jest-json-schema
|
json-schema.js
jest-json-schema
套件要先初始化。
1 2
| import { matchers } from 'jest-json-schema'; expect.extend(matchers);
|
測試就可以這樣寫
expect(json).toMatchSchema(schema);
|
unit test
axios-test.spec.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| import { shallowMount, createLocalVue } from "@vue/test-utils"; import store from "@/store"; import Actions from "@/views/Actions.vue"; import "../json-schema";
import axios from "axios"; jest.mock('axios');
describe('API get json', () => { const localVue = createLocalVue(); const wrapper = shallowMount(Actions, { store, localVue });
it('should get coscup data', done => { axios.get.mockResolvedValue({ data: { "en": "<ul><li><a href=\"http://registrano.com/events/coscup2011-regist\">Register</a></li>\n<li><a href=\"/2011/en/about/\">About Us</a></li>\n<li><a href=\"/2011/en/program/\">Program</a></li>\n<li><a href=\"/2011/en/venue/\">Venue</a></li>\n<li><a href=\"http://blog.coscup.org/\">Blog</a></li>\n<li><a href=\"/2011/en/sponsors/\">Sponsors</a></li>\n</ul>", "zh-tw": "<ul><li><a href=\"http://registrano.com/events/coscup2011-regist\">報名</a></li>\n<li><a href=\"/2011/zh-tw/about/\">活動簡介</a></li>\n<li><a href=\"/2011/zh-tw/program/\">議程</a></li>\n<li><a href=\"/2011/zh-tw/venue/\">地點</a></li>\n<li><a href=\"http://blog.coscup.org/\">部落格</a></li>\n<li><a href=\"/2011/zh-tw/sponsors/\">贊助單位</a></li>\n</ul>", "zh-cn": "<ul><li><a href=\"http://registrano.com/events/coscup2011-regist\">报名</a></li>\n<li><a href=\"/2011/zh-cn/about/\">活动</a></li>\n<li><a href=\"/2011/zh-cn/program/\">议程</a></li>\n<li><a href=\"/2011/zh-cn/venue/\">地点</a></li>\n<li><a href=\"http://blog.coscup.org/\">博客</a></li>\n<li><a href=\"/2011/zh-cn/sponsors/\">赞助单位</a></li>\n</ul>" } });
wrapper.find("#getJson").trigger("click"); wrapper.vm.$nextTick(async () => { const html = wrapper.find("pre"); const json = JSON.parse(html.text());
const schema = { properties: { "en": { type: 'string' }, "zh-tw": { type: 'string' }, "zh-cn": { type: 'string' } }, required: ['en', 'zh-tw'], } expect(json).toMatchSchema(schema); await expect(Object.keys(json).length).toBe(3); done() }) }); });
|
因為畫面需要再等一次渲染結束,才可以抓畫面的值。
所以要把測試寫在 $nextTick
裡面。
並且用非同步的方式 async-await
+ done()
測試 POST
本質上,是要測試 axios.post('url', data)
這一段裡的 data
是不是和 API 文件裡的一致
Components
Actions.vue
增加了一個 button 讓最後得到的 JSON 放在 Vuex 裡。
再透過 getters 放在 <pre>
裡。
1 2 3 4 5 6
| <template> <div class="text-align-center"> ... <button id="postJson" @click="$store.dispatch('createData', { hello: 'world' })">Create Data</button> </div> </template>
|
其中,直接從畫面觸發 Vuex 的 Actions , payload 用 { hello: 'world' }
。
而這個 payload 會直接放進 axios.post
的 data 中
unit test
在這要測試的目標,是函數的參數。
先 mock axios
套件,並且測它的 method 參數。
axios.post.mockResolvedValue
就是要定義 post
的成為「回傳 Promise.resolve()
的函數」。。在此 axios.post.mockResolvedValue({ name: 'chris'});
有定義 Promise 的回傳值,這個在這個例子沒有很重要,如果你的 post 有特定的 response 訊息,可以使用這個地方測試出產品程式的其它邏輯。
mockImplementation
可自訂函數內容。
axios-test.spec.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| describe('API post json', () => { const localVue = createLocalVue(); const wrapper = shallowMount(Actions, { store, localVue }); const mockAxios = axios.post.mockResolvedValue({ name: 'chris' }); it('should post data', () => { wrapper.find("#postJson").trigger("click");
const uri = mockAxios.mock.calls[0][0]; expect(uri).toBe('https://www.w3schools.com/js/demo_post2.asp');
const json = mockAxios.mock.calls[0][1]; const schema = { properties: { "hello": { type: 'string' }, }, required: ['hello'], } expect(json).toMatchSchema(schema); }); });
|