首页 > 解决方案 > 如何测试 Vuex 模块中的操作?

问题描述

我想测试一个名为 user 的 vuex 模块。

最初,我成功地将我的模块注册到了 Vuex。它按预期工作。

// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

import user from './modules/user'

Vue.use(Vuex)

const store = new Vuex.Store({
  modules: {
    user
  }
})

export default store

我的用户模块定义如下

store/modules/user.js

const state = {
  token: getToken() || '',
}

export const getters = {
  token: state => state.token,
}

const mutations = {
  [SET_TOKEN]: (state, token) => {
    state.token = token
  }
}

const actions = {
  [LOGIN] ({ commit }, body) {
    return new Promise((resolve, reject) => {
      login(body).then(response => { //login is an api method, I'm using axios to call it.
        const { token } = response.data
        setToken(token)
        commit(SET_TOKEN, token)
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  }
}

export default {
  state,
  getters,
  mutations,
  actions
}

登录接口

api/auth.js
import request from '@/utils/request'

export function login (data) {
  return request({
    url: '/auth/login',
    method: 'post',
    data
  })
}

axios 请求文件

utils/request
import axios from 'axios'
import store from '@/store'
import { getToken } from '@/utils/auth'

const request = axios.create({
  baseURL: process.env.VUE_APP_BASE_API_URL,
  timeout: 5000
})

request.interceptors.request.use(
  config => {
    const token = getToken()
    if (token) {
      config.headers['Authentication'] = token
    }
    return config
  }
)

export default request

当我想编写一些测试(使用Jest)时,例如如上所示的登录操作。

// user.spec.js
import { createLocalVue } from '@vue/test-utils'
import Vuex from 'vuex'

import actions from '@/store/modules/user'

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

test('huhu', () => {
  expect(true).toBe(true)
  // implementation..
})

如何为我的登录操作编写测试?谢谢。对不起我的初学者问题。

编辑:已解决谢谢 Raynhour 向我展示了正确的方向 :)

import { LOGIN } from '@/store/action.types'
import { SET_TOKEN } from '@/store/mutation.types'
import { actions } from '@/store/modules/user'
import flushPromises from 'flush-promises'

jest.mock('@/router')
jest.mock('@/api/auth.js', () => {
  return {
    login: jest.fn().mockResolvedValue({ data: { token: 'token' } })
  }
})

describe('actions', () => {
  test('login olduktan sonra tokeni başarıyla attı mı?', async () => {
    const context = {
      commit: jest.fn()
    }
    const body = {
      login: 'login',
      password: 'password'
    }
    actions[LOGIN](context, body)
    await flushPromises()
    expect(context.commit).toHaveBeenCalledWith(SET_TOKEN, 'token')
  })
})

标签: vue.jsjestjsvue-test-utils

解决方案


存储它只是一个将导出对象的 javascript 文件。不需要使用 vue test util。

import actions from '../actions'
import flushPromises from 'flush-promises'
jest.mock('../api/auth.js', () => {
  return {
   login: jest.fn()..mockResolvedValue('token')
  }; // mocking API. 

describe('actions', () => {
  test('login should set token', async () => {
    const context = {
      commit: jest.fn()
    }
    const body = {
      login: 'login',
      password: 'password'
    }
    actions.login(context, body)
    await flushPromises() // Flush all pending resolved promise handlers
    expect(context.commit).toHaveBeenCalledWith('set_token', 'token')
  })
})

但是您需要记住,在单元测试中,所有异步请求都必须被模拟(使用 jest.mock 或其他东西)


推荐阅读