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

Node.js测试时出现TypeError: axios is not a function错误求助

解决TypeError: axios is not a function问题

问题背景

在Node.js中使用axios发送POST请求,运行测试时持续抛出TypeError: axios is not a function,错误指向requestToken函数中的const axios = require('axios');语句。

原service.js代码

const axios = require('axios');
const qs = require('qs');

const requestToken = async (apiURL, reqBody) => {
  const postBody = qs.stringify({
    client_id: reqBody.client_id,
    client_secret: reqBody.client_secret,
    grant_type: reqBody.grant_type,
    'content-type': reqBody.content_type,
  });
  const postHeaders = {
    'Content-Type': 'application/json',
    'Content-Length': JSON.stringify(postBody).length,
    Host: new URL(apiURL).hostname,
    Connection: 'keep-alive',
  };
  const config = {
    method: 'POST',
    url: apiURL,
    headers: postHeaders,
    data: postBody,
  };
  const response = await axios(config); // 错误指向此处
  return response;
};

原service.test.js代码

const qs = require('qs');
const axios = require('axios');
const {requestToken } = require('../../libs/service');

const apiConfig = {
  TOKEN_REQ_BODY: {
    client_id: 'client_id',
    client_secret: 'client_secret',
    grant_type: 'grant_type',
    content_type: 'content_type',
  },
  AUTH_BASE_URL: 'uri',
  TOKEN_HEADER: {
    appkey: 'appkey',
  },
  API_BASE_URL: 'API_BASE_URL',
};
const tokenAxiosCalledWith = {
  method: 'POST',
  url: apiConfig.AUTH_BASE_URL,
  headers: apiConfig.TOKEN_HEADER,
  data: qs.stringify({
    client_id: apiConfig.TOKEN_REQ_BODY.client_id,
    client_secret: apiConfig.TOKEN_REQ_BODY.client_secret,
    grant_type: apiConfig.TOKEN_REQ_BODY.grant_type,
    'content-type': apiConfig.TOKEN_REQ_BODY.content_type,
  }),
};
const accessToken = {
  data: {
    access_token: 'access_token',
  },
};
const eventData = {
  metadata: {
    method: 'POST',
    uri: 'uri',
  },
  uriparams: 'uriparams',
  payload: tokenAxiosCalledWith.data,
};
const requestHeaders = {
  Authorization: accessToken.data.access_token,
  appkey: apiConfig.TOKEN_HEADER.appkey,
  'content-type': 'application/json',
};
const reqBody = {
  method: eventData.metadata.method,
  baseURL: apiConfig.API_BASE_URL,
  url: eventData.metadata.uri,
  responseType: 'json',
  headers: requestHeaders,
  params: eventData.uriparams,
  data: eventData.payload,
};
jest.mock('axios', () => jest.fn(() => accessToken));

describe('API service', () => {
it('is called with requestToken', (done) => {
    /* eslint-disable no-unused-vars */
    requestToken('https://token', reqBody).then((response) => {
      expect(axios).toHaveBeenCalledTimes(1);
      done();})
      .catch((e) => {
        done(e);
        });
    });
}

错误原因

  1. axios版本兼容问题:axios v1.0.0+对CommonJS模块导出方式做了变更,直接require('axios')得到的是包含default属性的模块对象,而非可直接调用的axios函数。
  2. 测试mock不匹配:原测试中mock的axios结构与实际导出结构不符,导致service.js中获取的axios不是可调用函数。
  3. reqBody结构错误:测试中传入的reqBody是axios请求配置,而非requestToken函数所需的包含client_id等字段的参数对象。
  4. 请求头与请求体不匹配:service.js中设置Content-Type: application/json,但请求体是qs.stringify生成的form-urlencoded格式,会导致请求解析失败。

修复步骤

1. 修正service.js中的axios导入

将const axios = require('axios');改为const axios = require('axios').default;,获取正确的axios函数。同时修正请求头格式,并添加函数导出。

修改后的service.js:

const axios = require('axios').default;
const qs = require('qs');

const requestToken = async (apiURL, reqBody) => {
  const postBody = qs.stringify({
    client_id: reqBody.client_id,
    client_secret: reqBody.client_secret,
    grant_type: reqBody.grant_type,
    'content-type': reqBody.content_type,
  });
  // 修正Content-Type为form-urlencoded,匹配qs.stringify生成的请求体
  const postHeaders = {
    'Content-Type': 'application/x-www-form-urlencoded',
    Host: new URL(apiURL).hostname,
    Connection: 'keep-alive',
  };
  const config = {
    method: 'POST',
    url: apiURL,
    headers: postHeaders,
    data: postBody,
  };
  const response = await axios(config);
  return response;
};

// 导出函数供测试调用
module.exports = { requestToken };

2. 修正测试文件的mock与参数

  • 调整jest.mock结构,模拟axios的默认导出;
  • 修改reqBody为requestToken所需的参数结构;
  • 使用async/await替代done回调,简化测试代码。

修改后的service.test.js:

const qs = require('qs');
const axios = require('axios').default;
const { requestToken } = require('../../libs/service');

const apiConfig = {
  TOKEN_REQ_BODY: {
    client_id: 'client_id',
    client_secret: 'client_secret',
    grant_type: 'grant_type',
    content_type: 'content_type',
  },
  AUTH_BASE_URL: 'uri',
  TOKEN_HEADER: {
    appkey: 'appkey',
  },
  API_BASE_URL: 'API_BASE_URL',
};
const accessToken = {
  data: {
    access_token: 'access_token',
  },
};
// 修正reqBody结构,匹配requestToken所需参数
const reqBody = {
  client_id: apiConfig.TOKEN_REQ_BODY.client_id,
  client_secret: apiConfig.TOKEN_REQ_BODY.client_secret,
  grant_type: apiConfig.TOKEN_REQ_BODY.grant_type,
  content_type: apiConfig.TOKEN_REQ_BODY.content_type,
};

// 模拟axios的默认导出结构
jest.mock('axios', () => ({
  default: jest.fn(() => Promise.resolve(accessToken))
}));

describe('API service', () => {
  it('is called with requestToken', async () => {
    await requestToken('https://token', reqBody);
    expect(axios).toHaveBeenCalledTimes(1);
  });
});

验证

运行测试后,TypeError: axios is not a function错误将被解决,测试会正常执行并验证axios调用次数。

内容的提问来源于stack exchange,提问作者R.Almoued

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:20:22