如何使用 Vue-test-utils 和 Jest 测试 Vuex 突变

Posted

技术标签:

【中文标题】如何使用 Vue-test-utils 和 Jest 测试 Vuex 突变【英文标题】:How to test Vuex Mutations using Vue-test-utils and Jest 【发布时间】:2019-05-28 03:01:30 【问题描述】:

我已经检查了至少一个 tutorials 的 couple 来模拟和测试 Vuex 动作,但我无法自己成功地实现它们。尽管我遵循了上面链接中提供的大部分步骤,但它总是会导致 toHaveBeenCalledfalse。您可以模拟操作,而不必使用jest.fn() 复制它们的实际功能,对吗?我不明白为什么我仍然无法成功完成。

store.js

export default new Vuex.Store(
  state: 
    currentSequence: ''
  ,
  actions: 
    runGenerator( commit, state , currentSequence) 
      // do something with currentSequence
    
  
)

Home.vue(请注意,这不是该组件的全部代码,但我列出了重要的代码,包括 submit.prevent 方法、包含表单的 html 以及调用 vuex 操作的位置)

<template>
  <v-app id="inspire">
    <v-form @submit.prevent="setNextVal" id="sequence-form">
      <!-- form contents here -->
    </v-form>
  </v-app>
</template>

<script>
import  mapActions  from 'vuex'

export default 
  methods: 
    setNextVal() 
      this.runGenerator(this.form.currentSequence)
      this.form.currentValue = this.getCurrentValue
    ,
    ...mapActions([
      'runGenerator'
    ]),
  

</script>

store.spec.js

import  shallowMount, createLocalVue  from '@vue/test-utils'
import Vue from 'vue'
import Vuex from 'vuex'
import Vuetify from 'vuetify'
import Home from '@/views/Home.vue'

const localVue = createLocalVue()

localVue.use(Vuex)
Vue.use(Vuetify)

describe('Home.vue', () => 

  let actions
  let store

  beforeEach(() => 
    actions = 
      runGenerator: jest.fn()
    
    store = new Vuex.Store(
      state: 
        currentSequence: ''
      ,
      actions
    )
  )

  it('Dispatches "runGenerator" when submit.prevent has been triggered', () => 
    const wrapper = shallowMount(Home,  store, localVue )
    const form = wrapper.find('#sequence-form')
    form.trigger('submit.prevent')

    expect(actions.runGenerator).toHaveBeenCalled()
  )
)

运行测试后出现以下错误:

expect(jest.fn()).toHaveBeenCalled() 预期的模拟函数已被调用,但没有被调用

我错过了什么?请各位大神赐教。我一直在阅读网上提供的参考资料,但我似乎无法在网上找到其他解决方案。

【问题讨论】:

如果你在 setNextVal() 中添加了一个 console.log,你能确认你在你的 jest 输出中看到了 log 语句输出,验证 form.trigger 是否工作? 【参考方案1】:

即使您在模拟这些操作,它们在技术上仍然是异步的。在测试 vuex 时,我总是等待带有 flushPromises 的异步操作(确保在继续执行之前解决任何活动的 Promise)。要将 flushPromises 添加到您的项目中,请执行以下操作:

npm i -D flush-promises

然后在你的测试中:

import flushPromises from 'flush-promises'

//...

it('Dispatches "runGenerator" when submit.prevent has been triggered', async() => 
    const wrapper = shallowMount(Home,  store, localVue )
    const form = wrapper.find('#sequence-form')
    form.trigger('submit.prevent')

    await flushPromises();    

    expect(actions.runGenerator).toHaveBeenCalled()
)

请注意,测试函数现在标记为 async-

【讨论】:

以上是关于如何使用 Vue-test-utils 和 Jest 测试 Vuex 突变的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 vue-test-utils 打开 bootstrap-vue 模态?

如何在单元测试期间使用带有 shallowMount 的 vue-test-utils 找到元素组件?

VueJs 如何删除全局错误处理程序以使用 vue-test-utils 进行测试

vue-test-utils:如何在 mount() 生命周期钩子(使用 vuex)中测试逻辑?

如何使用 vue-test-utils 和 Jest 在 Nuxt 中对使用 vuex-module-decorators 语法定义的 Vuex 模块进行单元测试?

如何使用 vue-test-utils 在单元测试期间触发窗口事件