4

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!!!

skyboyer
  • 15,149
  • 4
  • 41
  • 56
rbansal
  • 98
  • 12

1 Answers1

0

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.

futurelucas4502
  • 310
  • 3
  • 10
  • I appreciate the answer but the problem is the test case not working, the axis instance works fine with all calls. I need to fix the mocking part – rbansal May 19 '20 at 13:37
  • im not 100% sure what you mean as the line that is causing an error in the screenshot now works with the changes i made – futurelucas4502 May 19 '20 at 13:58
  • currently the output of `response.results` is undefined as the API doesnt return any data however if i do `response` i get a console log with all the info about the request. Console logs: https://pastebin.com/r17iRfQX – futurelucas4502 May 19 '20 at 14:01
  • i am sorry for not being clear but the issue i am facing is that the error occurs when i run 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); }); }); ``` the test case has been mentioned in the question as well – rbansal May 19 '20 at 16:15