如何用Jest模拟Axios API调用?Vuex异步Action测试报错求助
解决Vuex Action中Axios调用的Jest测试报错问题
嘿,我来帮你搞定这个问题!你遇到的TypeError: Cannot destructure property data of 'undefined' or 'null'本质是因为用jest.mock('axios')把Axios mock之后,没有给axios.get设置返回值,它默认返回undefined,Action里解构const { data } = await axios.get(url)自然就报错了。另外你的测试代码还有几个小细节需要修正,我一步步给你讲清楚:
第一步:修正测试代码的基础问题
你的测试里有两个明显的错误:
- 调用
actions.updateSearchValue时,把第二个参数name传成了jest.fn(),这不对,应该传一个真实的字符串(比如'test keyword'),因为Action里要把它拼接到URL里 - 断言时写的
expect(commit).toHaveBeenCalledWith('updateSearchValue', name)和实际逻辑不符,Action里第一个commit的是'storeSearchValue',得对应上
第二步:Mock Axios.get的返回值
既然用了Jest mock Axios,我们得给axios.get设置一个resolved的Promise,返回包含data属性的对象,这样Action里解构data就不会报错了。模拟的返回结构要和你Action里用到的data.result对应上。
完整的修正后测试代码
import actions from '@/store/modules/data/data-actions.js' import axios from 'axios'; // 你的Action里没用到路由,所以可以删掉这些多余的导入 // import VueRouter from 'vue-router'; // import { createLocalVue } from '@vue/test-utils'; // const localVue = createLocalVue(); // localVue.use(VueRouter); jest.mock('axios'); describe('data actions', () => { test('updateSearchValue should commit search value and fetch news data', async () => { // 1. 准备测试用的依赖和模拟数据 const commit = jest.fn(); const testKeyword = 'test keyword'; const mockNewsData = { result: [{ id: 1, title: 'Test News' }] }; // 2. 给mock的axios.get设置返回值 axios.get.mockResolvedValue({ data: mockNewsData }); // 3. 调用要测试的Action await actions.updateSearchValue({ commit }, testKeyword); // 4. 验证所有逻辑是否正确执行 // 验证第一个commit:存储搜索关键词 expect(commit).toHaveBeenCalledWith('storeSearchValue', testKeyword); // 验证axios.get被正确调用,URL拼接正确 const expectedUrl = `${process.env.VUE_APP_URL_API_News}/news?q=${testKeyword}`; expect(axios.get).toHaveBeenCalledWith(expectedUrl); // 验证第二个commit:存储从API拿到的新闻数据 expect(commit).toHaveBeenCalledWith('storeNewsData', mockNewsData.result); }); });
可选:测试API调用失败的场景
如果你的Action里有错误处理逻辑,还可以加一个失败场景的测试:
test('updateSearchValue should handle API request failure', async () => { const commit = jest.fn(); const testKeyword = 'test keyword'; const mockError = new Error('API request failed'); // 让mock的axios.get抛出错误 axios.get.mockRejectedValue(mockError); // 调用Action并验证错误被抛出 await expect(actions.updateSearchValue({ commit }, testKeyword)).rejects.toThrow(mockError); // 验证搜索关键词的存储仍然执行了 expect(commit).toHaveBeenCalledWith('storeSearchValue', testKeyword); });
总结报错原因
当你用jest.mock('axios')时,Jest会把Axios的所有方法替换成默认返回undefined的mock函数。所以await axios.get(url)得到的是undefined,你尝试解构{ data }就会触发TypeError。通过axios.get.mockResolvedValue({ data: mockData }),我们让mock函数返回一个符合业务逻辑的响应对象,这样Action里的解构就能正常工作了。
内容的提问来源于stack exchange,提问作者Erika
相关产品推荐
相关产品推荐

