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

标签 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()
  })
})

本质上,我正在尝试使用具有默认存储的 createWrapper 方法,除非传递 overridescustomizer 。当我运行测试时,出现以下错误

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

[vuex] unknown getter: getDashBoardData

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

[Vue warn]: Error in render: "TypeError: Cannot read property 'length' of undefined"

现在我有两个问题:

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

如果我只是在 beforeEach 内声明包装器,这样我就可以通过一些测试,但对于其他测试,我需要覆盖 gettersactions ,除非我有工厂函数,否则我无法做到这一点

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

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

任何帮助将不胜感激!

最佳答案

通过在 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()
  })

关于javascript - 如何用工厂功能组织Vue单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58607152/

相关文章:

javascript - Flickity轮播: Wrap prev and next buttons inside a custom div

javascript - 防止内容可编辑 div 中脚本注入(inject)的最佳方法

java - Java 中的 Liquibase 回滚似乎不起作用

javascript - 使用模态 Bootstrap-vue 获取背景上的事件点击

javascript - Vue.js 缓存方法结果?

javascript - 单击javascript关闭 Accordion

javascript - 为什么 JavaScript UpdateExpression 语法如此定义?

java - 使用 Mockito 测试重复代码

python - 对mock.sentinel对象的操作

javascript - 在 vue.js 中动态添加元素