简体   繁体   中英

Testing Vuex action that calls external api

In my Vue.js project I have the following Vuex action:

import { HTTP } from '@/services/http'

export const actions = {
  loginUser ({ commit }, params) {
    HTTP.post(
      'v1/login',
      { email: params.email, password: params.password }
    ).then(response => {
      localStorage.setItem('access_token', response.data.token)
      commit('SET_USER', response.data)
    }).catch(error => {
      commit('SET_LOGIN_ERROR', error.response.data.error)
    })
  }
}

I'm using Mocha + Karma for unit tests. How can I test that action?

It's important that you mock/stub any dependencies. Your first challenge is mocking the HTTP service because, as written, your tests won't pass unless you have an Internet connection to the backend server. Look into dependency injection to solve this.

To test actions, I borrowed the idea from Vuex's suggestion . Create a stub of the commit function that accepts the type and payload of each mutation the action calls and then compare that to what is expected. If the list of expected mutations match the list of mutations the commit stub calls when the action is executed, then the action passes the test.

This is a trivial example that I wouldn't use in production, but it helps to illustrate the idea:

let count = 0
let errors = []
let mutations = [
  { type: 'SET_USER', payload: 'whatever response.data is expected to be' }
]

function commit(type, payload) {
  const mutation = mutations[count]

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

  count++
}

actions.loginUser({ commit }, { email: 'fake@email.com', password: '12345' })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM