Search code examples
reactjsunit-testingmockingjestjsspy

How to spy on a default exported function with Jest?


Suppose I have a simple file exporting a default function:

// UniqueIdGenerator.js
const uniqueIdGenerator = () => Math.random().toString(36).substring(2, 8);

export default uniqueIdGenerator;

Which I would use like this:

import uniqueIdGenerator from './UniqueIdGenerator';
// ...
uniqueIdGenerator();

I want to assert in my test that this method was called while keeping the original functionality. I'd do that with jest.spyOn however, it requires an object as well as a function name as parameters. How can you do this in a clean way? There's a similar GitHub issue for jasmine for anyone interested.


Solution

  • I ended up ditching the default export:

    // UniqueIdGenerator.js
    export const uniqueIdGenerator = () => Math.random().toString(36).substring(2, 8);
    

    And then I could use and spy it like this:

    import * as UniqueIdGenerator from './UniqueIdGenerator';
    // ...
    const spy = jest.spyOn(UniqueIdGenerator, 'uniqueIdGenerator');
    

    Some recommend wrapping them in a const object, and exporting that. I suppose you can also use a class for wrapping.

    However, if you can't modify the class there's still a (not-so-nice) solution:

    import * as UniqueIdGenerator from './UniqueIdGenerator';
    // ...
    const spy = jest.spyOn(UniqueIdGenerator, 'default');