【问题标题】:(0 , _axios.default) is not a function when mocking axios with interceptors(0 , _axios.default) 在使用拦截器模拟 axios 时不是函数
【发布时间】:2020-08-31 15:55:54
【问题描述】:

我的应用程序有一个文件,它创建一个带有拦截器的 axios 实例,然后 api 使用这个实例进行调用。问题是当我尝试为此 api 编写测试时,它会因TypeError: (0 , _axios.default) is not a function 错误而失败。

下面是创建 axios 实例的 poc:

const axiosInstance = axios.create({
  timeout: 20000,
  paramsSerializer(params) {
    return qs.stringify(params, { indices: false });
  },
});

axiosInstance.interceptors.request.use((config) => {
  if (process.env.NODE_ENV === 'development') {
    logger.info(`Request sent to ${config.url}`, config.params);
  }

  return config;
}, (error) => Promise.reject(error));

axiosInstance.interceptors.response.use((response) => {
  if (process.env.NODE_ENV === 'development') {
    logger.info(`Response from ${response.config.url}`, response.data);
  }

  return parseBody(response);
}, (error) => parseError(error));

export default axiosInstance;

这是使用axios实例的api

const triviaAPI = {
  getQuestions: async (amount) => axiosInstance({
    method: 'get',
    url: 'https://opentdb.com/api.php',
    params: {
      amount,
    },
  }).then((response) => response.results)
    .catch((error) => {
      throw error;
    }),
};

export default triviaAPI;

这是 axios 模拟

import mockAxios from 'jest-mock-axios';

export default {
  ...mockAxios,
  ...{
    create: jest.fn(() => ({
      ...mockAxios,
      defaults: {
        headers: {
          common: {},
        },
      },
      interceptors: {
        request: {
          use: jest.fn(),
        },
        response: {
          use: jest.fn(),
        },
      },
      get: jest.fn(() => Promise.resolve({ data: { total_payout: 100.21 } })),
    })),
  },
};

最后这是测试用例

describe('triviaAPI', () => {
  it('should return a successful response', async () => {
    const data = await triviaAPI.getQuestions(10);
    console.log(data);
    expect(Array.isArray(data)).toBe(true);
  });
});

当我运行测试时,我得到以下错误

我已经搜索了很多,但还没有找到解决方案。请帮忙!!!

【问题讨论】:

    标签: javascript node.js jestjs axios


    【解决方案1】:

    它可能无法正常工作的原因是因为您使用的是 export,默认情况下 nodejs 尚不支持它,但是您可以使用引用 here 的实验性 node.js 功能启用它,但不推荐这样做,因此我会推荐使用esm

    所以对于您的用例:

    package.json

    {
      "name": "axios-test",
      "version": "1.0.0",
      "description": "",
      "main": "main.js",
      "scripts": {
        "test": "node -r esm ." //Important
      },
      "author": "",
      "license": "ISC",
      "dependencies": {
        "axios": "^0.19.2",
        "esm": "^3.2.25" //Important
      }
    }
    

    axiosInstance.js

    import axios from "axios" //Important
    
    const axiosInstance = axios.create({
        timeout: 20000,
        paramsSerializer(params) {
            return JSON.stringify(params, { indices: false });
        },
    });
    
    axiosInstance.interceptors.request.use((config) => {
        if (process.env.NODE_ENV === 'development') {
            logger.info(`Request sent to ${config.url}`, config.params);
        }
    
        return config;
    }, (error) => Promise.reject(error));
    
    axiosInstance.interceptors.response.use((response) => {
        if (process.env.NODE_ENV === 'development') {
            logger.info(`Response from ${response.config.url}`, response.data);
        }
    
        return response;
    }, (error) => Promise.reject(error));
    
    export default axiosInstance; //Important
    

    ma​​in.js

    import axiosInstance from "./axiosInstance.js" //Important
    
    const triviaAPI = {
        getQuestions: async (amount) => axiosInstance({
            method: 'get',
            url: 'https://opentdb.com/api.php',
            params: {
                amount,
            },
        }).then((response) => response.results)
            .catch((error) => {
                throw error;
            }),
    };
    
    async function main() {
        const data = await triviaAPI.getQuestions(10);
        console.log(data);
    }
    
    main()
    

    注意:我的 axiosInstance.mjs 中的一些代码已更改,因为问题不包括它们是什么所以我用//Important标记了所有相关更改

    另外:如果您想查看使用实验功能的示例,请查看此答案的编辑历史记录。

    【讨论】:

    • 我很欣赏这个答案,但问题是测试用例不起作用,轴实例在所有调用中都能正常工作。我需要修复模拟部分
    • 我不是 100% 确定你的意思,因为在屏幕截图中导致错误的行现在适用于我所做的更改
    • 目前response.results 的输出未定义,因为API 不返回任何数据,但是如果我这样做response,我会得到一个控制台日志,其中包含有关请求的所有信息。控制台日志:pastebin.com/r17iRfQX
    • 我很抱歉不清楚,但我面临的问题是当我运行测试用例时发生错误 ``` describe('triviaAPI', () => { it('should返回一个成功的响应', async () => { const data = await triviaAPI.getQuestions(10); console.log(data); expect(Array.isArray(data)).toBe(true); }); }) ; ```问题中也提到了测试用例
    猜你喜欢
    • 2019-06-26
    • 2019-10-02
    • 2020-06-10
    • 2018-01-20
    • 2019-03-15
    • 1970-01-01
    • 2020-06-23
    • 2020-11-26
    • 1970-01-01
    相关资源
    最近更新 更多