Jest测试:验证axios请求成功时notify函数的指定调用参数
问题根源
你定义的notify是测试函数内的局部变量,和业务代码里调用的notify完全不是同一个引用,导致mock函数根本没被执行,所以会出现调用次数为0的报错。
解决方案
根据notify的引入方式,分两种情况处理:
情况1:notify是从其他模块导入的
假设业务代码是这样导入notify的:
import axios from 'axios'; import { notify } from './notify'; // 示例导入路径 export function deleteRecord(id) { return axios .delete(`/${id}`) .then(() => notify('success', 'Delete successful')) .catch(() => notify('error', 'Delete failed')); }
测试代码需要mock整个notify模块,让业务代码调用的是mock版本:
import axios from 'axios'; import { deleteRecord } from './your-module'; // 替换为你的业务文件路径 import { notify } from './notify'; // 提前mock notify模块,生成mock函数 jest.mock('./notify', () => ({ notify: jest.fn() })); // 同时mock axios模块,让delete方法成为mock函数 jest.mock('axios'); describe('deleteRecord', () => { it('成功删除时调用notify传入成功参数', async () => { const id = 1; // 模拟axios delete请求成功 axios.delete.mockResolvedValueOnce({ status: 200 }); await deleteRecord(id); expect(notify).toHaveBeenCalledWith('success', 'Delete successful'); }); it('删除失败时调用notify传入错误参数', async () => { const id = 2; // 模拟axios delete请求失败 axios.delete.mockRejectedValueOnce(new Error('请求失败')); await deleteRecord(id); expect(notify).toHaveBeenCalledWith('error', 'Delete failed'); }); });
情况2:notify是全局变量(比如挂载在window上)
如果业务代码里的notify是全局可用的,测试时需要mock全局对象上的notify:
import axios from 'axios'; import { deleteRecord } from './your-module'; jest.mock('axios'); describe('deleteRecord', () => { // 每次测试前重置全局notify的mock beforeEach(() => { global.notify = jest.fn(); }); it('成功删除时调用全局notify传入成功参数', async () => { const id = 1; axios.delete.mockResolvedValueOnce({ status: 200 }); await deleteRecord(id); expect(global.notify).toHaveBeenCalledWith('success', 'Delete successful'); }); it('删除失败时调用全局notify传入错误参数', async () => { const id = 2; axios.delete.mockRejectedValueOnce(new Error('请求失败')); await deleteRecord(id); expect(global.notify).toHaveBeenCalledWith('error', 'Delete failed'); }); });
关键注意点
- 必须确保业务代码调用的
notify和测试里mock的是同一个引用 - 异步测试一定要加
await,等待promise执行完成后再做断言 - axios的mock要提前设置,确保
delete方法是jest mock函数
内容的提问来源于stack exchange,提问作者Jane Day
相关产品推荐
相关产品推荐

