What is the current behavior?
jest.mock(moduleName, func) throws the error, the second argument of jest.mock must be a function if func is defined as:
function func() {
return 'Hello';
}
...but works if the func is defined inline as an arrow function:
jest.mock(moduleName, () => 'Hello')
In both cases moduleName is a string like 'fs'
What is the expected behavior?
Either of:
the second argument of jest.mock must be an arrow functionjest.mock accept a function that's not an arrow functionThis is in a bare-bones Node app that doesn't use Babel and has index.js that prints a message to console.
It accepts functions, it just doesn't accept references. If you'd like, you could send a PR to babel-plugin-jest-hoist to adjust the error message to say must be an inline function. What do you think?
@cpojer is there a good reason why mock it doesn't accept function reference?
Yes, because your mock may be required before references are fully initialized. It's easier to see jest.mock calls as fully isolated, and the function as an isolated module scope.
Consider a module Banana that depends on Kiwi, which is mocked:
import Banana from './Banana';
jest.mock('Kiwi', () => name);
const name = ''I am a pear';
When Banana requires Kiwi, we know Kiwi is mocked. We run the function and then it throws saying name does not exist/is not initialized, simply because it is sequentially executed:
BananaBanana requires KiwiKiwi is mocked, and runs the mock function.name.name isn't initialized yetThis is why you cannot reference anything from the outer scope. Hope that makes sense.
Thanks! See https://github.com/facebook/jest/pull/4593
Hi, is there a way to automatically call mock on every test suite? I ran into this (now updated) error message when trying to create a mock module for i18n and call it as jest.mock('react-i18next', fn);.
I know this function will be required in multiple modules so I am trying to avoid writing this fix in every test.
jest.mock('react-i18next', () => ({
// this mock makes sure any components using the translate HoC receive the t function as a prop
translate: () => Component => props => <Component t={() => ''} {...props} />,
}));
@lmenus add your mock to a file called react-i18next in __mocks__. See https://facebook.github.io/jest/docs/en/manual-mocks.html
@SimenB Ah, missed that, thank you! This certainly reduces it to a mere jest.mock('react-i18next'); now!
Most helpful comment
Yes, because your mock may be required before references are fully initialized. It's easier to see
jest.mockcalls as fully isolated, and the function as an isolated module scope.Consider a module Banana that depends on Kiwi, which is mocked:
When Banana requires Kiwi, we know Kiwi is mocked. We run the function and then it throws saying
namedoes not exist/is not initialized, simply because it is sequentially executed:BananaBananarequiresKiwiKiwiis mocked, and runs the mock function.name.nameisn't initialized yetThis is why you cannot reference anything from the outer scope. Hope that makes sense.