iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 23
1
Modern Web

Vue 怎麼寫測試系列 第 23

Day 23. 實作一個電商網站 - 購物車

  • 分享至 

  • xImage
  •  

前言

加入購物車的按鈕要怎麼寫測試?
要用到 vuex 嗎?
如果用的話,actions, state, mutations 要怎麼測?
每次開發總是想得太遠,做得太少?

正文

寫測試的目的之一,我想是你有多少能力測多少事
已最小可行性當作出發點吧

所以首先當然是拋開 vuex,

設想一下,當我們今天要加入購物車
最簡單的作法是什麼?

就是在 data property 多一個地方可以存就好了
然後,有個按鈕會把選到的產品 id 加到購物車的 Object 裡面

所以我們一開始的測試可以這樣寫

it('按加入,要把產品 id 和數量加到購物車', () => {
  expectTo.click('.add-to-cart-button')
  expect(wrapper.vm.cart.products.length).toEqual(1)
  expect(wrapper.vm.cart.products[0].id).toEqual(1)
  expect(wrapper.vm.cart.products[0].count).toEqual(1)
})

it('如果產品已經在購物車,數量 +1', () => {
  expectTo.click('.add-to-cart-button')
  expect(wrapper.vm.cart.products.length).toEqual(1)
  expect(wrapper.vm.cart.products[0].id).toEqual(1)
  expect(wrapper.vm.cart.products[0].count).toEqual(1)

  expectTo.click('.add-to-cart-button')
  expectTo.click('.add-to-cart-button')
  expectTo.click('.add-to-cart-button')
  expect(wrapper.vm.cart.products.length).toEqual(1)
  expect(wrapper.vm.cart.products[0].id).toEqual(1)
  expect(wrapper.vm.cart.products[0].count).toEqual(4)
})
<button class="add-to-cart-button" @click="addToCart"> 加入購物車</button>

methods: {
    addToCart () {
        // 加到 cart object
    }
},
data: {
    ...
    cart: {
      products: []
    },
}

有了這個雛形之後,我想多做一點改變
把購物車用 vuex 去實作

在 /store 裡面新增一個 index.js
簡單放一點功能

export const state = () => ({
  cart: {
    products: []
  }
})

export const mutations = {
  add (state, productId) {
    let product = state.cart.products.find(
        product => product.id === productId
    )
    
    product ? 
        product.count += 1 : 
        this.cart.products.push({id: productId, count: 1})
  }
}

那我們的原本加入購物車的邏輯就要調整
回去 LandingPage.vue, 把 vuex 設定近來

import { mapState, mapMutations } from 'vuex'

export default {

    computed: {
        ...mapState(['cart'])
        
        // 省略其他的內容
    },

    methods: {
        ...mapMutations(['add']),

        // 這樣就可以直接使用了
        addToCart () {
            this.add(this.selectedProductId)
        }
        
        // 省略其他的內容
    }
}

這時候會發現我們的測試壞掉了,這是正常的
我們的測試只是沒設定 Vuex 而已
這邊我們要怎麼修呢

先讓 vue 知道我們要用 vuex

import { mount, shallow, createLocalVue } from 'vue-test-utils'
import Vuex from 'vuex'

const localVue = createLocalVue()
localVue.use(Vuex)

再來在 beforeEach 的區塊,mock vuex 的所有內容

beforeEach(() => {

  mutations = {
    // 直接用個 stub function
    add: jest.fn(),
  }
  store = new Vuex.Store({
    state: {}, // 根本連什麼資料都不用設定
    mutations
  })
}

然後我們的測試,只需要確認我們的 stub function 有被使用就好

it('按加入,要觸發加入購物車的 action', () => {
  expectTo.click('.add-to-cart-button')
  expect(mutations.add).toHaveBeenCalled()
})

murmur

基本上我們把功能 mock 住,就代表我們信任那個 module
這個信任是很盲目的,還有時間的話 vuex 要單獨自己寫測試
這邊就建議用嚴格的 unit testing
畢竟是單純的邏輯, 跟畫面沒有關係


上一篇
Day 22. 實作一個電商網站 - 多方案的產品選擇
下一篇
Day 24. 實作一個電商網站 - 購物車(二)
系列文
Vue 怎麼寫測試30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言