Jest Spy on an exported function

The spyOn utility in Jest is incredibly versatile, enabling you to monitor, track, and even replace the behavior of functions. However, applying this to a named export from a module can be a bit tricky due to the specific parameters required by spyOn.

Consider the scenario where we're importing a specific function, targetFunction, from a module called @example/library:

import { targetFunction } from '@example/library'

You might wonder how to correctly use jest.spyOn to monitor this function, especially what argument to pass first. Jest's spyOn expects an object or module as the first parameter, and the name of the method to spy on as the second.

The trick to effectively monitoring a named export is to import the entire module's contents as an object, then pass this object into jest.spyOn. Here's how it's done:

import * as exampleLibrary from '@example/library'

jest.spyOn(exampleLibrary, 'targetFunction').mockReturnValue({ key: 42 })

Be aware that attempting this might sometimes result in a TypeError: Cannot redefine property: targetFunction due to Jest's handling of property definition. If you encounter this, it means spyOn cannot be used directly to mock this particular function. You'll need to employ an alternate strategy for mocking in such scenarios