Jest throws TypeError: (0 , _module.myFunction) is not a function, testing exported functions (non default) with Jest
Asked Answered
F

5

16

So I'm using Jest, Typescript and Create-react-app

I have this test:

import { defaultHeaders } from './http';

describe('http tests', () => {
  test('defaultHeaders()', () => {
    const headers = defaultHeaders(undefined);
    expect(headers).toEqual({ foo: 2 });
  });
});

The code is in same subdir in file http.ts and looks like this:

export function defaultHeaders(headers?: FetchHeaders): FetchHeaders {
  return { 'Content-Type': 'application/json' };
}

When I run my jest tests it throws:

TypeError: (0 , _http.defaultHeaders) is not a function

The weird part is that all other tests that are wrapped in a default function or const do work.

Is there any way to test non default exported functions with Jest?

update:

  • also tried converting defaultHeaders into an arrow function and that didn't help.
  • and tried changing import as: import * as http from './http' that still makes it throw same error
Facing answered 11/9, 2020 at 20:18 Comment(2)
There are no good reasons for this to happen, unless you redefined defaultHeaders export in the same file. A common case for an export to appear undefined is circular dependency but the code you posted doesn't suggest that. Please, provide stackoverflow.com/help/mcve that can reproduce the problem.Cypher
Debug what's imported with import * as http from './http' and import http from './http', it's only possible on your side. Also try const { defaultHeaders } = require('./http') and const { defaultHeaders } = require('./http').default. These attempts cover possibilities with incorrect TS module interoperation.Cypher
F
17

Update with Answer

So the issue was that in src/setupTest.ts I included a mock of the module without the function I was trying to test therefore it was undefined.

// mock our fetch wrapper to avoid doing http calls in tests
jest.mock('utilities/http/http', () => ({
  // NO defaultHeaders() function mocked that was the problem 
  getRequest: function () {
    return {
      json: {},
      status: 200,
    };
  },
  postRequest: function () {
    return {
      json: {},
      status: 200,
    };
  },
  request: function () {
    return {
      json: {},
      status: 200,
    };
  },
}));

If I remove the mocked from setupTest.ts then I can unit test it.

Facing answered 6/11, 2020 at 21:20 Comment(3)
Agreed. Check your test-setup.ts and make sure you didn't mistakingly mock something that shouldn't have been mocked.Houri
Great! Thank you so much! I spent hours solving the problem. It turned out in setupTests the module was mocked just for one function without requiring the actual of othersCw
Thanks! Obvious now I think of it but you saved me a bunch of time.Midship
G
2

When mocking with a jest.fn like this it also causes the problem:

const doThing = jest.fn();
jest.mock(
  '@/myfile',
  () => {
    return {
      doThing // Having a mock here - also causes the error.
    };
  },
  { virtual: true },
);

FIX

const JESTdoThing = jest.fn();
jest.mock(
  '@/myfile',
  () => {
    return {
      doThing: (x, y, z) => JESTdoThing(x, y, z)
    };
  },
  { virtual: true },
);

it('should run JESTdoThing', ()=> {
  thingWhichRunsDoThing();
  expect(JESTdoThing).toHaveBeenCalledTimes(1);
})
Guideboard answered 25/7, 2023 at 9:7 Comment(0)
T
0

In my case, the issue was on the path. I was testing a file named 'index.js' and I gave for granted that I didn't need to include it in the path when I was importing the function. I was wrong.

Wrong code:

import { myFunction } from '../my/path

Right code:

import { myFunction } from '../my/path/index.js
Toole answered 26/4, 2023 at 9:25 Comment(0)
I
0

In my case I had the same error when I forgot to desctructure my function when importing it in to my Jest test file.

Incorrect: import countScoresForPart2Strategy from "./countScoresForPart2Strategy";

Correct: import { countScoresForPart2Strategy } from "./countScoresForPart2Strategy";

Ioves answered 28/7, 2023 at 12:37 Comment(0)
L
0

I had this same problem.

import { handleChunk } from '../src/ai-utils';

Then

TypeError: aiUtils.handleChunk is not a function

In my case, it was that I had previously done a "build" command, which put .js files in the src directory. Then I added handleChunk but forgot to re-build, so it was referencing the old .js file instead of the .ts.

Lynden answered 15/6 at 13:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.