Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(0 , _axios.default) is not a function when mocking axios with interceptors

My app has a file which creates an instance of axios with interceptors and then the api's use this instance to make calls. The issue is when i try to write test for this api it fails with TypeError: (0 , _axios.default) is not a function error.

below is the poc which creates the axios instance:

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;

this is the api that uses the axios instance

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;

and this is the axios mock

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 } })),
    })),
  },
};

and finally this is the test case

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

when i run the test i get the below error enter image description here

I have searched around a lot but found no solution yet. Please help!!!

like image 724
rbansal Avatar asked Nov 06 '22 07:11

rbansal


1 Answers

The reason it may not be working is because you are using export which isnt yet supported in nodejs by default you can however enable it using an experimental node.js feature as referenced here however thats not recommended therefore i would recommend using esm

So for your use case:

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

main.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()

NOTICE: Some code was changed in my axiosInstance.mjs as the question didn't include what they were so I have marked all relevant changes with //Important

Also: If you want to see an example using the experimental features please check the edit history of this answer.

like image 142
futurelucas4502 Avatar answered Nov 11 '22 06:11

futurelucas4502