VueJS: Thử nghiệm

Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực

Các phần chính mà chúng tôi muốn thử nghiệm đơn vị trong Vuex là các mutation và action.

Thử nghiệm mutation

Rất dễ dàng để kiểm tra các mutation, bởi vì chúng chỉ là các hàm hoàn toàn dựa vào các đối số của chúng. Một mẹo là nếu bạn đang sử dụng các mô-đun ES2015 và đặt các mutation bên trong tệp store.js của bạn, ngoài việc export mặc định, bạn cũng nên export các mutation dưới dạng export có tên:

const state = { ... }

// export `mutations` as a named export
export const mutations = { ... }

export default new Vuex.Store({
  state,
  mutations
})

Ví dụ kiểm tra mutation bằng cách sử dụng Mocha + Chai (bạn có thể sử dụng bất kỳ thư viện framework/assertion nào bạn thích):

// mutations.js
export const mutations = {
  increment: state => state.count++
}
// mutations.spec.js
import { expect } from 'chai'
import { mutations } from './store'

// destructure assign `mutations`
const { increment } = mutations

describe('mutations', () => {
  it('INCREMENT', () => {
    // mock state
    const state = { count: 0 }
    // apply mutation
    increment(state)
    // assert result
    expect(state.count).to.equal(1)
  })
})

#Thử nghiệm action

Các action có thể phức tạp hơn một chút bởi vì chúng có thể gọi ra các API bên ngoài. Khi thử nghiệm action, ta thường cần phải làm một số mức mocking - ví dụ, chúng ta có thể tóm tắt các lời gọi API thành một dịch vụ và giả định dịch vụ đó bên trong các thử nghiệm của chúng ta. Để dễ dàng giả lập các dependecy, ta có thể sử dụng webpack và inject-loader để nạp các tệp thử nghiệm của chúng ta.

Ví dụ kiểm tra action không đồng bộ:

// actions.js
import shop from '../api/shop'

export const getAllProducts = ({ commit }) => {
  commit('REQUEST_PRODUCTS')
  shop.getProducts(products => {
    commit('RECEIVE_PRODUCTS', products)
  })
}
// actions.spec.js

// use require syntax for inline loaders.
// with inject-loader, this returns a module factory
// that allows us to inject mocked dependencies.
import { expect } from 'chai'
const actionsInjector = require('inject-loader!./actions')

// create the module with our mocks
const actions = actionsInjector({
  '../api/shop': {
    getProducts (cb) {
      setTimeout(() => {
        cb([ /* mocked response */ ])
      }, 100)
    }
  }
})

// helper for testing action with expected mutations
const testAction = (action, payload, state, expectedMutations, done) => {
  let count = 0

  // mock commit
  const commit = (type, payload) => {
    const mutation = expectedMutations[count]

    try {
      expect(type).to.equal(mutation.type)
      if (payload) {
        expect(payload).to.deep.equal(mutation.payload)
      }
    } catch (error) {
      done(error)
    }

    count++
    if (count >= expectedMutations.length) {
      done()
    }
  }

  // call the action with mocked store and arguments
  action({ commit, state }, payload)

  // check if no mutations should have been dispatched
  if (expectedMutations.length === 0) {
    expect(count).to.equal(0)
    done()
  }
}

describe('actions', () => {
  it('getAllProducts', done => {
    testAction(actions.getAllProducts, null, {}, [
      { type: 'REQUEST_PRODUCTS' },
      { type: 'RECEIVE_PRODUCTS', payload: { /* mocked response */ } }
    ], done)
  })
})

Nếu bạn có gián điệp trong môi trường thử nghiệm của mình (ví dụ: thông qua Sinon.JS ), bạn có thể sử dụng chúng thay vì helper testAction:

describe('actions', () => {
  it('getAllProducts', () => {
    const commit = sinon.spy()
    const state = {}
    
    actions.getAllProducts({ commit, state })
    
    expect(commit.args).to.deep.equal([
      ['REQUEST_PRODUCTS'],
      ['RECEIVE_PRODUCTS', { /* mocked response */ }]
    ])
  })
})

Thử nghiệm getters

Nếu getters của bạn có tính toán phức tạp thì cũng đáng để ta thử nghiệm chúng. Getters cũng rất đơn giản để kiểm tra với cùng một lý do như mutation.

Ví dụ thử nghiệm một getter:

// getters.js
export const getters = {
  filteredProducts (state, { filterCategory }) {
    return state.products.filter(product => {
      return product.category === filterCategory
    })
  }
}
// getters.spec.js
import { expect } from 'chai'
import { getters } from './getters'

describe('getters', () => {
  it('filteredProducts', () => {
    // mock state
    const state = {
      products: [
        { id: 1, title: 'Apple', category: 'fruit' },
        { id: 2, title: 'Orange', category: 'fruit' },
        { id: 3, title: 'Carrot', category: 'vegetable' }
      ]
    }
    // mock getter
    const filterCategory = 'fruit'

    // get the result from the getter
    const result = getters.filteredProducts(state, { filterCategory })

    // assert the result
    expect(result).to.deep.equal([
      { id: 1, title: 'Apple', category: 'fruit' },
      { id: 2, title: 'Orange', category: 'fruit' }
    ])
  })
})

#Chạy thử nghiệm

Nếu mutation và action của bạn được viết đúng cách, các kiểm tra sẽ không có sự phụ thuộc trực tiếp vào API của trình duyệt sau khi mô phỏng đúng cách. Vì vậy, bạn có thể chỉ cần bó các bài kiểm tra với webpack và chạy nó trực tiếp trong Node. Ngoài ra, bạn có thể sử dụng mocha-loader hoặc Karma + karma-webpack để chạy thử nghiệm trong trình duyệt thực.

#Chạy trong Node

Tạo cấu hình webpack sau (cùng với proper .babelrc):

// webpack.config.js
module.exports = {
  entry: './test.js',
  output: {
    path: __dirname,
    filename: 'test-bundle.js'
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      }
    ]
  }
}

Sau đó:

webpack
mocha test-bundle.js

#Chạy trong trình duyệt

  1. Cài đặt mocha-loader.
  2. Thay đổi cấu hình entry webpack ở trên thành 'mocha-loader!babel-loader!./test.js'.
  3. Bắt đầu sử dụng cấu hình webpack-dev-server.
  4. Tới localhost:8080/webpack-dev-server/test-bundle.

#Chạy trong Trình duyệt với Karma + karma-webpack

Tham khảo ý kiến ​​thiết lập trong tài liệu trình tải vue.

» Tiếp: Hot reloading
« Trước: Xử lý form
Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Copied !!!