Vuex+Jest中如何单元测试调用Store的Getter?
测试Vuex Getter的最佳实践
其实测试这种简单的Getter根本不需要复杂Mock整个Store——因为Vuex的Getter本质就是接收state和getters作为参数的纯函数,直接调用它并传入Mock数据就搞定了,这也是单元测试Getter最简洁高效的方式。
先给你举个具体的例子,假设你的Getter代码是这样的(比如在store/modules/urlModule.js里):
const getters = { fullUrl: (state) => `${state.baseUrl}/${state.path}` } export default { getters }
直接测试Getter函数(推荐)
测试时不需要碰Store实例,直接导入Getter,手动传Mock的state就行:
import { getters } from '@/store/modules/urlModule' describe('fullUrl getter', () => { it('应该正确拼接baseUrl和path', () => { // 1. 定义Mock的state const mockState = { baseUrl: 'http://foobar.com', path: 'user/profile' } // 2. 直接调用Getter函数,传入mockState const result = getters.fullUrl(mockState) // 3. 断言结果 expect(result).toBe('http://foobar.com/user/profile') }) })
如果你的Getter依赖其他Getters(比如用第二个参数getters),也可以一起Mock:
// 假设Getter依赖另一个getter const getters = { normalizedPath: (state) => state.path.replace(/\s+/g, '-'), fullUrl: (state, getters) => `${state.baseUrl}/${getters.normalizedPath}` } // 测试代码 it('应该使用规范化后的路径拼接URL', () => { const mockState = { baseUrl: 'http://foobar.com', path: 'user profile' } // Mock依赖的getters const mockGetters = { normalizedPath: 'user-profile' } const result = getters.fullUrl(mockState, mockGetters) expect(result).toBe('http://foobar.com/user-profile') })
为什么你之前会得到undefined?
你提到的http://foobar.com/undefined,大概率是因为尝试Mock Store实例时,没有正确把state注入到Getter的调用上下文里,导致Getter访问的state属性是undefined。而直接调用Getter函数、手动传参的方式,完全避免了这个问题——因为这就是Getter的本质工作方式:接收state作为参数,返回计算结果。
非要Mock完整Store实例?(不推荐,但可以做)
如果你的场景确实需要测试和Store实例绑定的逻辑(比如跨模块Getter),也可以用Vuex提供的方法创建Mock Store:
Vue3示例:
import { createStore } from 'vuex' import urlModule from '@/store/modules/urlModule' describe('fullUrl getter with mock store', () => { it('应该返回正确的拼接URL', () => { const store = createStore({ modules: { url: { state: { baseUrl: 'http://foobar.com', path: 'user/profile' }, getters: urlModule.getters } } }) expect(store.getters['url/fullUrl']).toBe('http://foobar.com/user/profile') }) })
Vue2示例:
import Vuex from 'vuex' import urlModule from '@/store/modules/urlModule' describe('fullUrl getter with mock store', () => { it('应该返回正确的拼接URL', () => { const store = new Vuex.Store({ modules: { url: { state: { baseUrl: 'http://foobar.com', path: 'user/profile' }, getters: urlModule.getters } } }) expect(store.getters['url/fullUrl']).toBe('http://foobar.com/user/profile') }) })
但还是那句话,这种方式完全没必要——单元测试Getter的核心是测试它的计算逻辑,直接调用函数传参就足够了,不需要引入Store实例的复杂度。
内容的提问来源于stack exchange,提问作者Samuel-Zacharie Faure
相关产品推荐
相关产品推荐

