You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何测试ES6类内的异步axios调用?解决测试报错问题

问题分析与修复方案

让我们一步步拆解你遇到的问题,逐个击破:

1. 业务代码中的核心问题

缺失handleAPIResponse方法

你的getUsers方法里调用了this.handleAPIResponse.call(...),但这个方法在MyClass中完全没有定义。当axios请求成功进入then回调时,这会直接抛出错误,进而触发catch块,这是导致后续报错的根源之一。

Catch块写法错误

原代码的catch块只是返回了errorHandler变量,而不是调用它并传入错误信息。正确的逻辑应该是调用errorHandler(error),否则即使进入错误分支,也不会执行预期的错误处理逻辑,还可能因为返回未执行的函数(或参数传递异常)触发TypeError。

修正后的业务代码:

import axios from 'axios';
export default class MyClass{
 constructor(config){
  this.config = config;
 }

 // 补上缺失的handleAPIResponse方法,根据业务逻辑处理响应并调用对应handler
 handleAPIResponse(resp, successHandler, errorHandler) {
  if (resp.data) {
    successHandler(resp.data);
    return resp.data;
  } else {
    errorHandler(new Error('Invalid response data'));
    return null;
  }
 }

 async getUsers(url, params, successHandler, errorHandler) {
  return axios.post(url, params)
   .then(resp => this.handleAPIResponse.call(this, resp, successHandler, errorHandler))
   .catch(error => {
     errorHandler(error);
     // 按需决定是否reject promise,确保调用方可以捕获错误
     return Promise.reject(error);
   });
 }
}

2. 测试代码中的变量名错误

你在测试里创建了instance = new MyClass(...),但调用getUsers时却用了myClass.getUsers——这个变量名拼写错误会导致调用异常,甚至让errorHandler参数无法正确传递,直接触发你看到的报错。

另外可以优化mock返回值,让它和handleAPIResponse的预期匹配。修正后的测试代码:

import MyClass from './mycode.js';
import axios from 'axios';
jest.mock('axios');

let instance; // 提前声明实例变量

beforeEach(() => {
 instance = new MyClass({ env: 'prod' });
});
afterEach(() => {
 jest.clearAllMocks();
});

test('should return all users and trigger successHandler', async () => {
 const successHandler = jest.fn();
 const errorHandler = jest.fn();
 const mockUserData = ['John Doe', 'Charles'];

 axios.post.mockImplementationOnce(() => {
  return Promise.resolve({ data: mockUserData });
 });

 const response = await instance.getUsers('url', {}, successHandler, errorHandler);

 expect(response).toEqual(mockUserData);
 expect(successHandler).toHaveBeenCalledTimes(1);
 expect(successHandler).toHaveBeenCalledWith(mockUserData);
 expect(errorHandler).not.toHaveBeenCalled();
});

// 新增错误场景测试,覆盖catch分支
test('should trigger errorHandler when request fails', async () => {
 const successHandler = jest.fn();
 const errorHandler = jest.fn();
 const mockError = new Error('Request timeout');

 axios.post.mockImplementationOnce(() => {
  return Promise.reject(mockError);
 });

 await instance.getUsers('url', {}, successHandler, errorHandler);

 expect(errorHandler).toHaveBeenCalledTimes(1);
 expect(errorHandler).toHaveBeenCalledWith(mockError);
 expect(successHandler).not.toHaveBeenCalled();
});

3. 关于__mocks__/axios.js的说明

你的mock文件写法是没问题的,测试中用mockImplementationOnce会临时覆盖默认mock行为,完全可以满足当前测试需求。如果后续需要统一默认返回值,再调整这个文件即可。

为什么会出现errorHandler is not a function?

当handleAPIResponse不存在时,then回调抛出错误进入catch块,原代码只是返回errorHandler变量;再加上测试里的变量名错误,导致errorHandler参数未正确传递,最终触发了这个类型错误。修复上述问题后,报错就会消失。

内容的提问来源于stack exchange,提问作者Vinay Mehta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:14:43