Search code examples
jestjsjest-fetch-mock

jest.mock(..) not working in 'describe' (TypeError: moduleName.split is not a function)


jest.mock(..) does not seem to work at the 'describe' level for my tests.

If I have the following :

import React from 'react';
import {someFunction} from "./something/someFile";

describe('Overview Test', () => {

    jest.mock(someFunction);

    test(' snapshot', () => {

    });
});

Then running the 'test' (ie. at the test level), works fine.

But if I run the 'describe' (ie. the describe level or suite level), then I get the following error :

TypeError: moduleName.split is not a function

    at Resolver.resolveModuleFromDirIfExists (A:\frontend\node_modules\jest-resolve\build\index.js:224:30)
    at Resolver.resolveModule (A:\frontend\node_modules\jest-resolve\build\index.js:252:12)

If I have this :

describe('Overview Test', () => {
    test(' snapshot', () => {
        jest.mock(someFunction);
    });
});

Then both ways it does not work.

I have also tried this :

import React from 'react';
import {someFunction} from "./something/someFile";


describe('Overview Test', () => {

    beforeEach(() => {
        jest.mock(someFunction);
    });

    test(' snapshot', () => {

    });
});

And it does not work.

UPDATE

I have also tried this and it does not work :

import React from 'react';
import {someFunction} from "./something/someFile";

    describe('Overview Test', () => {

        jest.mock('./something/someFile', () => {
            return { someFunction: jest.fn(() => "futhissit")};
        });

        test(' snapshot', () => {
            someFunction()
        });
    });

Solution

  • Jest mock is for mocking modules and the first argument is the moduleName which it has to be a valid module name (inside node_modules or a file path) and not a direct function/module:

    jest.mock(moduleName, factory, options)

    Mocks a module with an auto-mocked version when it is being required. factory and options are optional.

    The error you're getting TypeError: moduleName.split is not a function is because resolveModuleFromDirIfExists tries to split the module name/path and you can see it inside jest-resolve/src/index.ts at line 207.

    When you want to test an ES module, you pass the module location for the moduleName and you create a factory using __esModule: true and then create properties with exported functions being mocked using jest.fn():

    someFile.js exports the someFunction:

    module.exports.someFunction = () => 'Some function result!';
    

    Mocking someFile.js module using jest.mock()

    describe('Overview Test', () => {
    
      // Mock the module and its functions
      jest.mock('./someFile', () => ({
        __esModule: true,
        someFunction: jest.fn(() => 'Mocked someFunction!')
      }));
    
      // Import the function from the mocked module
      const { someFunction } = require('./someFile');
    
      test('snapshot', () => {
        // Execute the mocked function
        const someResult = someFunction();
    
        // Expect to return the mocked value
        expect(someResult).toBe('Mocked someFunction!');
      });
    
    });
    

    You have to import the mocked modules after the jest.mock module mocking. You can create a jest.setup.js and configure it using setupFilesAfterEnv that can have your mocks inside it and then just import the modules like normal at the top of the test files.