iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 24
0
Modern Web

Vue菜鳥的自我學習days系列 第 24

24.Rxjs 處理非同步3

Unit test
因應更動需要更改測試程式,product-service.get 方法已經改為回傳 Observable 物件,因此需要更改回傳內容,
在 src/services 底下新增 mocks 資料夾,並新增一個 product-service.js 作為 stub service

import { Observable } from 'rxjs';
const mockProducts = [
{
id: 1,
name: 'Product I',
imgUrl: 'https://images.pexels.com/photos/1200458/pexels-photo-1200458.jpeg?
auto=compress&cs=tinysrgb&h=350',
desc: 'Description',
price: 20.00,
},
];
const mockProduct = {
id: 1,
name: 'Product I',
imgUrl: 'https://images.pexels.com/photos/1200458/pexels-photo-1200458.jpeg?
auto=compress&cs=tinysrgb&h=350',
desc: 'Description',
price: 20.00,
};
export default {
get(id) {
return Observable.create((observer) => {
if (id) {
observer.next({ response: mockProduct });
} else {
observer.next({ response: mockProducts });
}
observer.complete();
});
},
};

因為需要回傳 Observable 物件,使用 rxjs 的 Observabale.create() 來建立,重點需要呼叫 observer.next() 來觸發資料更新,以及最後 observer.complete() 來完成 ,如此便完成 stub service
在 productList.spec.js 中,先引用 VueRx,並在實體中註冊

import Vue from 'vue';
import VueRx from 'vue-rx';
Vue.use(VueRx);

之後使用 jest.mock() 建立 stub service 物件,修改原先的 mock() 內容為:

jest.mock('@/services/product-service');

修改測試內容如下:

it('sets the correct data', () => {
const wrapper = shallowMount(ProductList);
const expected = [
{
id: 1,
name: 'Product I',
imgUrl: 'https://images.pexels.com/photos/1200458/pexels-photo-1200458.jpeg?
auto=compress&cs=tinysrgb&h=350',
desc: 'Description',
price: 20.00,
},
];
expect(wrapper.vm.products).toEqual(expected);
});

完整測試碼

import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vue from 'vue';
import VueRouter from 'vue-router';
import VueRx from 'vue-rx';
import ProductList from '@/views/ProductList';
import ProductInfo from '@/views/ProductInfo';
Vue.filter('currency', value => value);
Vue.use(VueRx);
jest.mock('@/services/product-service');
describe('ProductList.vue', () => {
it('sets the correct data', () => {
const wrapper = shallowMount(ProductList);
const expected = [
{
id: 1,
name: 'Product I',
imgUrl: 'https://images.pexels.com/photos/1200458/pexels-photo-1200458.jpeg?
auto=compress&cs=tinysrgb&h=350',
desc: 'Description',
price: 20.00,
},
];
expect(wrapper.vm.products).toEqual(expected);
});
it('trigger onProductClick method', () => {
const localVue = createLocalVue();
localVue.use(VueRouter);
const routes = [
{
path: '/product/:id',
name: 'productInfo',
component: ProductInfo,
},
];
const router = new VueRouter({ routes });
const wrapper = shallowMount(ProductList, { localVue, router });
wrapper.vm.$nextTick(() => {
wrapper.find('.product-container').trigger('click');
expect(wrapper.vm.$route.name).toMatch('productInfo');
});
});
});

productInfo.spec.js 參考上面作法


上一篇
23.Rxjs 處理非同步2
下一篇
25.eslint
系列文
Vue菜鳥的自我學習days39

尚未有邦友留言

立即登入留言