Mock.mockImplementation is not a function

10,679

I had similiar issues with mockimplementation is not a function and just realised I forgot the jest.setup.js file.

You probably already checked that, but have you looked in jest.setup.js instead of jest.config.js if you added the module there (jest.mock('...'));

That solved it for me as I wanted to mock a service. Was probably something I easily overlooked.

Share:
10,679

Related videos on Youtube

gomes
Author by

gomes

Full-Stack web developer with a preference for front-end logic. Also a merkle trees lover a.k.a blockchain developer.

Updated on June 04, 2022

Comments

  • gomes
    gomes almost 2 years

    I've tried to search every single similar issue here, unfortunately no solution worked for me.

    I'm currently trying to mock named exports from a module, that looks like this:

    module.ts

    export function someFunctionOne() {
        // implementation
    }
    
    export const someFunctionTwo = function (
    ) {
        // implementation
    }
    
    export const someFunctionThree = () => {
        // implementation
    }
    
    export const someFunctionFour = () => {
        // implementation
    }
    

    There are four exports here, and in my tests, I need to mock the whole module:

    • Two exports shall be mocked initially to some value, then re-mocked by some tests (but not all)
    • Two exports shall only be mocked initially and do not need to be re-mocked as I rely on the same mock for every tests

    Tests look like this:

    module.test.ts

    import React from 'react'
    import { shallow } from 'enzyme'
    import Component from './component' // component I am testing
    import { someFunctionOne, someFunctionTwo  } from './module'
    
    ;(jest as any).mock('./module', () => ({
        someFunctionOne: jest.fn(),
        someFunctionTwo: jest.fn(),
        someFunctionThree: jest.fn(() => 10),
        someFunctionFour: jest.fn((s) => s),
    }))
    ;(someFunctionOne as any).mockReturnValue('some String')
    ;(someFunctionTwo as any).mockReturnValue(false)
    
    
    describe('Component', () => {
        beforeEach(() => {
            ;(someFunctionOne as any).mockReset()
            ;(someFunctionTwo as any).mockReset()
        })
        it('renders', () => {
            ;(someFunctionOne as any).mockImplementationOnce(jest.fn(() => 'some string'))
            ;(someFunctionTwo as any).mockImplementationOnce(jest.fn(() => false))
            const shallowRenderedModule = shallow(
                <Module>
                    <div>Children textContent here</div>
                </Module>
            )
            expect(shallowRenderedModule).toMatchSnapshot()
        })
        // Then, many other tests...
    })
    

    I also have jest and babel-jest configured as so:

    jest.config.js

    module.exports = {
        displayName: 'redacted-app',
        setupFilesAfterEnv: ['./jest/jest.setup'],
        preset: '../../jest.preset.js',
        transform: {
            '^.+\\.[tj]sx?$': [
                'babel-jest',
                { cwd: __dirname, configFile: './babel-jest.config.json' },
            ],
            '\\.(svg)$': './jest/svg.transform',
        },
        moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
    }
    
    

    babel-jest.config.json

    {
        "presets": [
            [
                "@babel/preset-env",
                {
                    "targets": {
                        "node": "current"
                    }
                }
            ],
            "@babel/preset-typescript",
            "@babel/preset-react"
        ]
    }
    
    

    The problem is, no matter what method I use from Mock (mockImplementation, mockReturnValue, etc) I always end up with _moduleName.someFunctionOne.mockReturnValue is not a function:

        TypeError: _moduleName.someFunctionOne.mockReturnValue is not a function
    
          10 |      someFunctionFour: jest.fn((s) => s),
          11 | }))
        > 12 | ;(someFunctionOne as any).mockReturnValue('some String')
             |                     ^
          13 | ;(someFunctionTwo as any).mockReturnValue(false)
    
    

    console.logging it, it seems that indeed, the exports aren't actually mocked.

    I'm at a loss here, what could it be? I've tried:

    • Using a dummy function inside the original jest.fn() e.g jest.fn(() => {})
    • Not using a jest mock function at all in the original mock e.g someFunctionOne: () => {}
    • Not using mockReturnValue in line 12 and mock it directly in jest.fn()
    • Chaining mockImplementationOnce to the initial module mock

    But none of these worked.

    • Estus Flask
      Estus Flask about 3 years
      There should be __esModule: true in module mock. But that someFunctionOne is not undefined means that a mock simply wasn't applied. This can happen if jest.mock isn't hoisted, this is specific to your project and likely means that you misconfigured Jest and Babel.
    • gomes
      gomes about 3 years
      @EstusFlask I forgot to mentioned that I've tried that as well. However I simply disregarded it as unrelated, as _esModule should simply bring support to mock default exports for ESM, which I don't use here as you've correctly noted. Is there anything specific you would look out for in jest and babel config?
    • Estus Flask
      Estus Flask about 3 years
      __esModule affects how named exports are handled. Omitting it may result in a module with no named exports. See jestjs.io/docs/next/code-transformation#defaults . You need babel-jest to be in effect somehow.
    • gomes
      gomes about 3 years
      I've tried using _esModule again and can confirm the named exports are the same as before. Also, I'm using babel-jest, so I've just posted the config for jest and babel-jest. I don't see anything that could cause it there. One thing to note is I'm using nx to manage the monorepo this project is part of, I thought it could've potentially been the issue but explicitly running jest --config=jest.config.js produces the same error.
    • Estus Flask
      Estus Flask about 3 years
      I don't see obvious problem there. Try to mock it a way it should definitely fail, jest.mock('./module', () => null). If it doesn't try to avoid hoisting by changing import to require and putting it below jest.mock.