Vitest mock Axios在Vuex store测试中不生效问题解决
Vitest mock Axios 测试Vuex Action失败问题解决
问题表现
测试Vue2+Vitest项目的Vuex store时,getters、mutations这类纯同步逻辑的测试可以正常运行,但包含axios get请求的action测试始终失败。
另外确认测试实践相关疑问:Vue项目中分别独立测试Vuex store和组件是不是行业通用最佳实践?是不是两类代码都需要做测试覆盖?
待测试的Store代码(tag.js)
import axios from "axios"; const actions = { async fetchTags({ commit }) { try { const response = await axios.get( CONST_CONFIG.VUE_APP_URLAPI + "tag?OrderBy=id&Skip=0&Take=100" ); commit("setTags", response.data); } catch (error) { console.log(error); return; } }, }; export default { state, getters, actions, mutations, };
对应测试代码(tag.spec.js)
import { expect } from "chai"; import { vi } from "vitest"; import axios from "axios"; vi.mock("axios", () => { return { default: { get: vi.fn(), }, }; }); describe("tag", () => { test("actions - fetchTags", async () => { const users = [ { id: 1, name: "John" }, { id: 2, name: "Andrew" }, ]; axios.get.mockImplementation(() => Promise.resolve({ data: users })); axios.get.mockResolvedValueOnce(users); const commit = vi.fn(); await tag.actions.fetchTags({ commit }); expect(axios.get).toHaveBeenCalledTimes(1); expect(commit).toHaveBeenCalledTimes(1); }); });
报错信息
FAIL tests/unit/store/apiObject/tag.spec.js > tag > actions - fetchTags AssertionError: expected "spy" to be called 1 times ❯ tests/unit/store/apiObject/tag.spec.js:64:24 62| await tag.actions.fetchTags({ commit }); 63| 64| expect(axios.get).toHaveBeenCalledTimes(1); | ^ 65| expect(commit).toHaveBeenCalledTimes(1); 66| });
- 预期调用次数:1
- 实际调用次数:0
之前试过参考同类问题的解决方案,甚至改用TS编写测试用例,报错完全一致,问题没有解决。
根因与修复
问题根源在vitest.config.ts配置文件:项目代码里用到了全局配置变量CONST_CONFIG,但Vitest运行环境下没有注入这个变量,导致action执行到拼接请求地址的代码时就抛出了CONST_CONFIG is not defined的错误,被catch分支直接捕获,根本没走到后续axios.get的调用逻辑,所以mock的spy统计到的调用次数是0。
修复方式是在Vitest配置的define字段中注入全局的CONST_CONFIG变量,修复后的完整配置如下:
import { resolve } from "path"; var configApi = require("./public/config.js"); const { createVuePlugin } = require("vite-plugin-vue2"); const r = (p: string) => resolve(__dirname, p); export default defineConfig({ test: { globals: true, environment: "jsdom", }, define: { CONST_CONFIG: configApi, }, plugins: [createVuePlugin()], resolve: { alias: { "@": r("."), "~": r("."), }, }, });
关于Vue测试实践的说明
分开独立测试Vuex store和组件是通用的最佳实践:
- Store测试聚焦状态流转、异步请求逻辑、mutation/action的触发正确性,不需要挂载组件,执行速度快,问题定位精准
- 组件测试聚焦视图渲染、用户交互、props/emit传值逻辑,测试时可以直接mock掉store依赖,隔离视图层和状态层的逻辑
两类代码都需要覆盖测试,分别保障状态层和视图层的逻辑正确性。
内容的提问来源于stack exchange,提问作者Bigoudi88
相关产品推荐
相关产品推荐

