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

Posted

技术标签:

【中文标题】vue-test-utils:如何在 mount() 生命周期钩子(使用 vuex)中测试逻辑?【英文标题】:vue-test-utils: How to test logic within mounted() lifecycle hook (with vuex)? 【发布时间】:2018-10-21 01:36:59 【问题描述】:

我正在尝试为 Vue 的 mounted() 生命周期钩子中的逻辑编写单元测试,但运气不佳。问题似乎是当组件使用 vue-test-utils mount 挂载时,mounted() 永远不会被调用。这是我要测试的 Vue 组件:

<template>
  <div></div>
</template>

<script>   
export default 
  name: 'MyComponent',
  mounted () 
    this.$store.dispatch('logout')
  

</script>

还有测试本身:

import  mount, createLocalVue  from '@vue/test-utils'
import Vuex from 'vuex'
import MyComponent from '@/components/MyComponent'

const localVue = createLocalVue()

localVue.use(Vuex)

describe('MyComponent.vue', () => 
  let store
  let actions

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

  it('calls store "logout" action', () => 
    mount(MyComponent,  localVue, store )
    expect(actions.logout).toHaveBeenCalled()
  )
)

但是,这会失败,expect(logout).toHaveBeenCalled() 断言为 false。

如果我直接使用 actions.logout() 调用模拟存储操作,则测试通过,并且我还有其他测试也调用存储操作,例如按下按钮,并且这些操作也通过了,所以问题肯定出现在mount() 生命周期钩子。

有什么想法吗?

(vue 2.5.4 和 vue-test-utils 1.0.0-beta-.15)

【问题讨论】:

刚刚用指定的版本测试了你的代码,它可以工作。 尝试使用1.0.0-beta.16,今天发布了 【参考方案1】:

不知道有什么不同,但我将商店模拟抽象到另一个文件中,现在一切似乎都正常了。

mocks.js

export const storeMock = Object.freeze(
  state: ,
  actions: 
    logout: jest.fn().mockName('logout')
  ,
)

test.spec.js

import  shallowMount, createLocalVue  from '@vue/test-utils'
import Vuex from 'vuex'
import  storeMock  from './mocks.js' 
import MyComponent from '@/components/MyComponent'

const localVue = createLocalVue()

localVue.use(Vuex)

describe('MyComponent.vue', () => 
  let options

  beforeEach(() => 
    jest.clearAllMocks()
    const store = new Vuex.Store(storeMock)
    options =  store, localVue 
  )

  it('calls store "logout" action', () => 
    shallowMount(MyComponent, options)
    expect(storeMock.actions.logout).toHaveBeenCalled()
  )
)

【讨论】:

【参考方案2】:

没有将 store 模拟抽象到另一个文件,并且没有beforeEach 的方法略有不同(由于某种原因破坏了我的测试)。

import  createLocalVue, shallowMount  from "@vue/test-utils";
import Vuex from "vuex";
import MyComponent from "@/components/MyComponent.vue";

describe("MyComponent", () => 
  const localVue = createLocalVue();
  localVue.use(Vuex);

  const actions = 
    logout: jest.fn()
  ;
  const store = new Vuex.Store( actions );

  const wrapper = shallowMount(MyComponent, 
    localVue,
    store
  );

  it('calls store "logout" action', () => 
    expect(actions.logout).toHaveBeenCalled();
  );
);

【讨论】:

以上是关于vue-test-utils:如何在 mount() 生命周期钩子(使用 vuex)中测试逻辑?的主要内容,如果未能解决你的问题,请参考以下文章

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

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

如何在单元测试期间使用 vue-test-utils 和 jest 模拟 mixin?

如何测试 Vue.js mixin 的模板?

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

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