Jest: having trouble keeping a reference of a mock function with `jest.fn()`

Joji

I wanted to mock out a function and make sure it has executed a certain number of times. The tricky part is that the function I wanted to mock out is part of the returned result of another function My implementation is roughly like

const theFnIWantedToMock = jest.fn()
jest.mock('../hooks', () => {
  const actualHooks = jest.requireActual('../hooks')
  return {
    ...actualHooks,
    someHooks() {
      return 
       {
          theFnIWantedToMock,
        }
    }
  }
})

describe('test', () => {
  it('some test', () => {
    //...
    expect(theFnIWantedToMock).toHaveBeenCalledTimes(1) 
  })
})

but Jest is throwing an error saying that Invalid variable access theHookINeedToMock. Does anyone know what is the correct way of doing it?

Estus Flask

This problem is described in the documentation:,

A limitation with the factory parameter is that, since calls to jest.mock() are hoisted to the top of the file, it's not possible to first define a variable and then use it in the factory. An exception is made for variables that start with the word 'mock'. It's up to you to guarantee that they will be initialized on time! For example, the following will throw an out-of-scope error due to the use of 'fake' instead of 'mock' in the variable declaration

Prefixing a variable with mock disables Jest check. let or const variables are in temporal dead zone before declaration, that they are accessed when a factory is evaluated results in runtime error in untranspiled ES6. For eagerly evaluated mocked modules a mock needs to be defined inside a factory.

A way to avoid this is to use var declaration that is hoisted and initialize it inside a factory:

var theFnIWantedToMock
jest.mock('../hooks', () => {
  const actualHooks = jest.requireActual('../hooks')
  theFnIWantedToMock = jest.fn()
  return {
    ...actualHooks,
    someHooks: jest.fn().mockReturnValue(theFnIWantedToMock),
  }
})

A way to keep a reference to it is to keep it a part of the import:

jest.mock('../hooks', () => {
  const actualHooks = jest.requireActual('../hooks')
  const theFnIWantedToMock = jest.fn()
  return {
    ...actualHooks,
    theFnIWantedToMock,
    someHooks: jest.fn().mockReturnValue(theFnIWantedToMock),
  }
})

This makes theFnIWantedToMock available as a part of import object, also works for reusable mocks in __mocks__.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related