如何使用工厂功能组织Vue单元测试?

时间:2019-10-29 12:06:32

标签: javascript unit-testing vuejs2 jestjs vue-test-utils

我正在尝试使用工厂函数为Dashboard.vue组件编写单元测试,以便可以根据需要覆盖storewrapper

这是代码

import { mount, createLocalVue } from '@vue/test-utils'
import mergeWith from 'lodash.mergewith'
import mutationobserver from 'mutationobserver-shim'
import Vuex from 'vuex'
import BootstrapVue from 'bootstrap-vue'
import Dashboard from '@/views/dashboard/Dashboard'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { library as faLibrary } from '@fortawesome/fontawesome-svg-core'
import { faUser, faThumbsUp, faSignOutAlt, faBorderAll, faAlignJustify, faTrashAlt, faRandom } from '@fortawesome/free-solid-svg-icons'
import flushPromises from 'flush-promises'

jest.mock('@/services/app.service.js')

faLibrary.add(faUser, faThumbsUp, faSignOutAlt, faBorderAll, faAlignJustify, faTrashAlt, faRandom)

const localVue = createLocalVue()
localVue.use(Vuex)
localVue.use(BootstrapVue)
localVue.use(mutationobserver) // This is a necessary polyfill for Bootstrap-Vue
localVue.component('font-awesome-icon', FontAwesomeIcon)

function customizer (ovjValue, srcValue) {
  /*
      If the property that takes precedence is an array,
      overwrite the value rather than merging the arrays
    */
  if (Array.isArray(srcValue)) {
    return srcValue
  }
  /*
      If the property that takes precedence is an empty object,
      overwrite the property with an empty object
     */
  if (srcValue instanceof Object && Object.keys(srcValue).length === 0) {
    return srcValue
  }
}

describe('DashBoard component tests', () => {
  let state
  // let actions
  // let getters
  let store
  let wrapper

  let dashBoardData = [
    { db_name: 'Jobs', dxp_dashboardref: 1, dxp_hidden: 0, dxp_position: 1, dxp_ref: 926 },
    { db_name: 'Firms', dxp_dashboardref: 2, dxp_hidden: 0, dxp_position: 2, dxp_ref: 927 },
    { db_name: 'CRM', dxp_dashboardref: 5, dxp_hidden: 0, dxp_position: 3, dxp_ref: 987 }
  ]

  // beforeEach(() => {
  state = {
    auth: {
      user: {
        auids: '',
        md_clock: 0,
        md_picture: '',
        ps_fname1: '',
        ps_surname: '',
        psname: 'Test Test',
        psref: 0
      }
    },
    app: {
      dashBoardData: []
    }
  }

  function createStore (overrides) {
    const defaultStoreConfig = {
      // state: {
      //   state
      // },
      getters: {
        getDashBoardData: () => dashBoardData
      },
      actions: {
        loadDashboard: jest.fn(),
        updateDashBoardData: jest.fn()
      }
    }
    return new Vuex.Store(
      state,
      mergeWith(defaultStoreConfig, overrides, customizer)
    )
  }

  function createWrapper (overrrides) {
    const defaultMountingOptions = {
      localVue,
      store: createStore()
    }
    return mount(
      Dashboard,
      mergeWith(
        defaultMountingOptions,
        overrrides,
        customizer)
    )
  }

  // START: Testing existence of DOM Elements tests
  it('is a Vue instance', () => {
    const wrapper = createWrapper({})
    expect(wrapper.isVueInstance).toBeTruthy()
  })
})

从本质上讲,除非传递createWrapperoverrides,否则我将尝试使用具有默认存储的customizer方法。运行测试时,出现以下错误

  

console.error node_modules / vuex / dist / vuex.common.js:899

     

[vuex]未知的吸气剂:getDashBoardData

     

console.error node_modules / vue / dist / vue.runtime.common.dev.js:621

     

[Vue警告]:渲染错误:“ TypeError:无法读取未定义的属性'length'”

现在,我有两个问题:

  1. 为什么在unknown getter中声明了defaultStoreConfig我会被抛出?
  2. 第二个错误来自state。由于某种原因,它无法识别我正在传递的状态变量。有什么想法吗?

如果我像这样简单地在beforeEach中声明包装器,以便可以通过我的一些测试,但是对于需要覆盖gettersactions的其他测试,我不是能够做到这一点,除非我具有工厂功能

    getters = {
      getDashBoardData: () => dashBoardData
   },
    actions = {
    loadDashboard: jest.fn(),
    updateDashBoardData: jest.fn()
  }

  store = new Vuex.Store({
    state,
    actions,
    getters
  })
  })

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

通过在defaultStoreConfig内部传递状态而不是在创建商店时单独传递状态来解决此问题

代码:

    const defaultStoreConfig = {
      state: {
        auth: {
          user: {
            auids: '',
            md_clock: 0,
            md_picture: '',
            ps_fname1: '',
            ps_surname: '',
            psname: 'Test Test',
            psref: 0
          }
        },
        app: {
          dashBoardData: []
        }
      },
      getters: {
        getDashBoardData: () => dashBoardData
      },
      actions: {
        loadDashboard: jest.fn(),
        updateDashBoardData: jest.fn()
      }
    }

测试:

  it('is a Vue instance', () => {
    const wrapper = createWrapper()
    expect(wrapper.isVueInstance).toBeTruthy()
  })