vue-test-utils:如何测试Vue组件mounted钩子中的Vuex逻辑?
解决Vue组件mounted钩子测试不触发的问题
嘿,我正好在早期的vue-test-utils版本里踩过这个坑!让我来帮你搞定这个问题。
你测试失败的核心原因是:在vue-test-utils 1.0.0-beta.15这个早期beta版本中,结合localVue和Vuex使用时,直接传入store到mount选项的方式存在注入bug,导致组件实例里的this.$store是undefined。这样一来,mounted钩子中的this.$store.dispatch('logout')相当于调用一个不存在的方法,自然不会触发你的mock函数。
下面是几个可行的解决思路:
方案1:升级vue-test-utils版本(最推荐)
早期beta版本的vue-test-utils有很多未修复的bug,直接升级到更稳定的版本就能解决这个问题。建议升级到1.0.0-beta.29或更高版本(最好是正式稳定版)。你只需要修改package.json中的版本号,然后重新执行依赖安装命令即可:
npm install @vue/test-utils@^1.3.0 --save-dev # 或者用yarn yarn add @vue/test-utils@^1.3.0 --dev
升级后你的原有测试代码应该就能正常运行了。
方案2:移除localVue(如果测试允许)
如果你的测试不需要隔离Vue全局实例,可以直接去掉localVue的使用,直接挂载组件并传入store:
import { mount } from '@vue/test-utils' import Vuex from 'vuex' import MyComponent from '@/components/MyComponent' 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, { store }) expect(actions.logout).toHaveBeenCalled() }) })
方案3:通过mocks手动注入$store(必须用localVue时)
如果你的测试场景必须使用localVue来隔离环境,可以通过mount选项的mocks属性手动把store注入到组件中:
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, mocks: { $store: store } }) expect(actions.logout).toHaveBeenCalled() }) })
你也可以在组件的mounted钩子中加一行console.log(this.$store)来验证,如果测试时输出undefined,就说明确实是store注入的问题,用上面的方案就能解决。
内容的提问来源于stack exchange,提问作者cmasri
相关产品推荐
相关产品推荐

