'TypeError: _API.default is not a constructor with Jest tests

I have an API class that I am trying to use in a React app.

// API file

class API {
...
}

export default API;

// Other file
import API from "utils/API";

const api = new API();

And I am getting the error:

TypeError: _API.default is not a constructor

But.. it seems like my default is set?

My Jest setup is like this:

  "jest": {
    "setupFiles": [
      "./jestSetupFile.js"
    ],
    "testEnvironment": "jsdom",
    "preset": "jest-expo",
    "transformIgnorePatterns": [
      "node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg|react-router-native/.*|@invertase/react-native-apple-authentication/.*)"
    ]
  },

My strong guess is that this is due to a configuration of my babel, webpack or package.json.

What could be causing this?

Note, I want to be clear, this doesn't happen whatsoever in my main application, only in Jest testing


If I change it to a named export/import, I get this:

TypeError: _API.API is not a constructor

Extremely confusing behavior.



Solution 1:[1]

This was ultimately due to additional code inside the file that I was exporting the class from.

import { store } from "root/App";

if (typeof store !== "undefined") {
  let storeState = store.getState();
  let profile = storeState.profile;
}

At the top, outside my class for some functionality I had been working on.

This caused the class default export to fail, but only in Jest, not in my actual application.

Solution 2:[2]

As mentioned by others, it would be helpful to see a minimum reproducible example.

However, there is one other possible cause. Are you mocking the API class in your test file at all? This problem can sometimes happen if a class is mistakenly mocked as an "object" as opposed to a function. An object cannot be instantiated with a "new" operator.

For example, say we have a class file utils/API like so:

class API {
  someMethod() {
    // Does stuff
  }
}

export default API;

The following is an "incorrect" way to mock this class and will throw a TypeError... is not a constructor error if the class is instantiated after the mock has been created.

import API from 'utils/API';

jest.mock('utils/API', () => {
  // Returns an object
  return {
    someMethod: () => {}
  };
})

// This will throw the error
const api = new API();

The following will mock the class as a function and will accept the new operator and will not throw the error.

import API from 'utils/API';

jest.mock('utils/API', () => {
  // Returns a function
  return jest.fn().mockImplementation(() => ({
    someMethod: () => {}
  }));
})

// This will not throw an error anymore
const api = new API();

Solution 3:[3]

You'll need to export it like this :

export default class API

Solution 4:[4]

You could try with:

utils/API.js

export default class API {
...
}

test.js

import API from "utils/API";

const api = new API();

Solution 5:[5]

Trying adding "esModuleInterop": true, in your tsconfig.json. BY default esModuleInterop is set to false or is not set. B setting esModuleInterop to true changes the behavior of the compiler and fixes some ES6 syntax errors. Refer the documentation here.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Steven Matthews
Solution 2 JoshA
Solution 3 Ankit Gupta
Solution 4 Daniele Ricci
Solution 5 hari hara sankar