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');
Answer from thisismydesign on Stack Overflow
🌐
DhiWise
dhiwise.com › post › grow-testing-efficiency-with-jest-spyon-for-default-exports
A Deep Dive into Jest spyOn for Default Exports
April 30, 2025 - Learn how to spy on a React module's default export and test its implementation without affecting the actual implementation.
Discussions

Cannot spyOn default export of module
Describe the bug In Jest a common pattern for me was to spyOn the default export of a module. This no longer works in vitest. It throws the following error: TypeError: Cannot redefine property: def... More on github.com
🌐 github.com
6
February 25, 2022
spy on pure functions exported as const
Whether or not you can spy on these functions depends on what module type your app is targeting. If it is ES6, you do a default export in your helper file and spy on the functions via spyOn(defaultImport, ‘helperFn’). You cannot just spy on the function itself, since ES6 modules export read-only references to their exposed values (i.e., you can’t overwrite the reference with a spy). If you target commonjs, you can get away with it because the references are not actually read-only at runtime. You need to spy on the reference before your component/service that you’re testing is initialized, so before the TestBed calls for example. At least, this is what my app has experienced recently. More on reddit.com
🌐 r/Angular2
11
2
March 12, 2021
How to jest spyOn a commonJS default export
Is it possible to jest.spyOn a default export so that I can call the mockImplementation method to change what the function does before each test? More on stackoverflow.com
🌐 stackoverflow.com
June 9, 2020
Trouble testing ES6 default export with Jest
Hello friends, I'm calling the default export in my React app, eg axios({ url: "/foo/bar", method: "get" }), but have hit a wall when testing with Jest and trying to mock or spy on axios. I'm using the latest versions of Axios (0.24.0), ... More on github.com
🌐 github.com
2
January 18, 2022
🌐
Jest
jestjs.io › the jest object
The Jest Object · Jest
1 week ago - When importing a default export, it's an instruction to import the property named default from the export object: ... The third argument can be used to create virtual mocks – mocks of modules that don't exist anywhere in the system: ... Importing a module in a setup file (as specified by setupFilesAfterEnv) will prevent mocking for the module in question, as well as all the modules that it imports. Modules that are mocked with jest.mock are mocked only for the file that calls jest.mock.
🌐
GitHub
github.com › vitest-dev › vitest › issues › 855
Cannot spyOn default export of module · Issue #855 · vitest-dev/vitest
February 25, 2022 - Describe the bug In Jest a common pattern for me was to spyOn the default export of a module. This no longer works in vitest. It throws the following error: TypeError: Cannot redefine property: default ❯ eval test/suite.test.ts:5:16 3| i...
Author   AndrewLeedham
🌐
Code with Hugo
codewithhugo.com › jest-mock-spy-module-import
Jest Full and Partial Mock/Spy of CommonJS and ES6 Module Imports · Code with Hugo
October 15, 2019 - A default export can only be imported with a default import: import whateverIsDefault from './moduleY'. Theses 2 types of imports can also be mixed and matched, see import docs on MDN.
🌐
CopyProgramming
copyprogramming.com › howto › how-to-spy-on-a-default-exported-function-with-jest
How to Spy on a Default Exported Function with Jest: Complete 2026 Guide - Spy on a default exported function with jest complete
November 27, 2025 - The challenge with default exports is that they're not assigned to an object property you can directly access. When you import a default export like import myFunction from './utils', Jest doesn't have a conventional object property to spy on like it would with jest.spyOn(utils, 'myFunction').
🌐
Reddit
reddit.com › r/angular2 › spy on pure functions exported as const
r/Angular2 on Reddit: spy on pure functions exported as const
March 12, 2021 -

Lately I've been writing pure functions more and more in my code, they convey meaning very well, are easy to write and test

Now that most of my logic is in pure function I tend to write them outside of components because they don't depend on the state of the component.

Example getUsername is pure and not used in the template and as such doesn't really need to be a method of the component.

@Component({selector: ..., templateUrl: ..., styleUrls: ...})
export class UserComponent implements OnInit {
    @Input() user: User;
    username: string

    ngOnInit() {
        this.username = getUsername(this.user);
    }
}

export const getUsername = (user: User): string => `${user.firstname} ${user.lastname}`;

When I have too many of these pure functions I sometimes move them to a helper file.

Everything works perfectly, except when I try to spy on them for unit testing. At this point jasmine refuses to spy on them (relevant github issue)

What do you guys think I should do ? Move my pure functions to method of components ? Change my helper files into services eventhough they don't use any state ?

I feel like I have to remove relevant information from my code (purity of the functions) for the sole reason of unit testing and I don't like it

Edit: spying on an exported function used to work but stopped working with Angular 9, cf this github issue

🌐
Mercedes Bernard
mercedesbernard.com › blog › jest-mocking-strategies
Jest Mocking Strategies | Mercedes Bernard
July 12, 2020 - To mock getValue, we use a default import to import the entire module's contents, spy on the imported module's example property (this is the named export), and then chain a mock implementation to the returned mock function. In this case, our mock implementation is a function that returns an object with a getValue property, just like in our previous example. import * as exampleModule from "../namedFunctionReturnObject"; const mockExpected = "mock value"; jest.spyOn...
Find elsewhere
🌐
DEV Community
dev.to › tylerlwsmith › override-functions-in-individual-tests-using-jest-dp5
Mock functions in individual tests using Jest - DEV Community
August 5, 2024 - The Jest spyOn() documentation recommends resetting the state using jest.restoreAllMocks() in an afterEach() callback, which is what we did above. If we did not do this, the mock would return undefined in the next test after spyOn() was called. ... // esmModule.js export default function () { return "original default"; } export function named() { return "original named"; }
🌐
Chakshunyu
chakshunyu.com › blog › how-to-spy-on-a-named-import-in-jest
How To Spy On An Exported Function In Jest | A technical blog by Chak Shun Yu
import * as moduleApi from '@module/api'; // Somewhere in your test case or test suite jest.spyOn(moduleApi, 'functionToMock').mockReturnValue({ someObjectProperty: 42 }); One caveat to this approach is that there’s the chance that you will run across a TypeError: Cannot redefine property: functionToMock at Function.defineProperty (<anonymous>). In that case, you can’t use the spyOn function to mock the exported function.
🌐
Stack Overflow
stackoverflow.com › questions › 62276044 › how-to-jest-spyon-a-commonjs-default-export
How to jest spyOn a commonJS default export
June 9, 2020 - // code.js module.exports = () => { // some irrelevant code I want to rewrite with a mock }; // test const code = require('./code.js'); const mockCode = jest.spyOn(code, 'default'); // this line doesn't work with the error: "Cannot spy the default property because it is not a function; undefined given instead" it('some test', async () => { mockCode.mockImplementationOnce(() => { console.log('test') }); });
🌐
Jest
jestjs.io › es6 class mocks
ES6 Class Mocks · Jest
const playSoundFileMock = jest ... our class SoundPlayer has a getter method foo and a static method brand · export default class SoundPlayer { constructor() { this.foo = 'bar'; } playSoundFile(fileName) { console.log('Playing ...
🌐
Erikmartinjordan
erikmartinjordan.com › spy-non-default-function-react
Spy on non-default function using Jest's spyOn() — Erik Martín Jordán
February 21, 2022 - import * as Math from './Math.js' test('Mocking up default and non-default', async() => { // Spying on a non default exported function jest.spyOn(Math, 'sub').mockUpImplementation(() => 5) // Spying on the default exported function jest.spyOn(Math, 'default').mockImplementation(() => 5) }) Hi, I'm Erik, an engineer from Barcelona.
🌐
Code Your Greens
codeyourgreens.com › jest › mock-es6-modules
Mock ES6 Modules | Code Your Greens
If you need a named reference to spy on, or give to different implementations of the default export throughout your test file, here's how to do it: ... What if you want to use the actual implementation for everything, except for one or two things which you need to mock? ... Unfortunately you can't spread the jest.requireActual declaration directly inside the return body, you have to assign it to an intermediate variable.
🌐
GitHub
github.com › axios › axios › issues › 4397
Trouble testing ES6 default export with Jest · Issue #4397 · axios/axios
January 18, 2022 - // These all give the same error: jest.spyOn(axios, "default"); jest.mock("axios"); jest.doMock('axios', () => { return jest.fn() }) jest.mock('../moduleName', () => { return { __esModule: true, default: jest.fn(), }; ...
Author   ridgekuhn
🌐
DEV Community
dev.to › casconed › comment › akcj
This is super helpful, thank you. Can you shed any light on why importing use... - DEV Community
August 5, 2019 - Yup, so the issue is because we are spying on React.useState, which sets a spy on the default export from 'react'. Since you are pulling in useState as a named export, there is no spy on it.
🌐
Bitovi
bitovi.com › blog › mocking-modules-in-jest-tests
Mocking Modules in Jest Tests
August 6, 2024 - If you need to verify the invocation ... then choose jest.spyOn (you can use spyOn with any module export, such as a Class). The entire module must be imported into the test file—typically using the import * as module syntax. Note that by default, a Mock created by spyOn ...
🌐
Developright
developright.co.uk › posts › jest-mock-vs-jest-spyon-what-to-use-for-mocking.html
Jest.Mock vs Jest.SpyOn - What to use for Mocking
December 24, 2024 - Overall Jest.Mock works best when wanting to mock entire files: which contain named or default exports or specific named or default exports of a file for the entire duration of the test. Another way to mock within Jest is to make use of Jest.SpyOn function which lets you spy on specific exported ...
🌐
Developright
developright.co.uk › posts › mocking-functions-or-methods-with-jest.html
Mocking & Spying with Jest SpyOn | DevelopRight.co.uk
December 30, 2022 - // import package import randomLibrary from './libraries/random'; // inside test (shortened for brevity) jest.spyOn(randomLibrary, 'functionOrMethod'); The following will mock all of randomLibrary's exports with the default jest.fn() implementation.