为何Jest中使用requireActual/genMockFromModule需访问default属性?
.default for ES Module Default Exports in Jest Manual Mocks Let’s break down exactly why you hit that error and why adding .default fixes the problem:
1. ES Modules vs. CommonJS: The Interop Quirk
Your original module uses ES module default export (export default class {...}). When Jest (which relies on Node.js’s module system) loads an ES module via require.requireActual or jest.genMockFromModule, it wraps the ES module in a CommonJS-compatible object. The class you exported as the default ends up attached to the .default property of this wrapper object.
The Jest example you looked at uses CommonJS export (module.exports = class User {...}) instead. With CommonJS, require directly returns the class itself—no wrapper, no .default needed. That’s why the example never mentions this step: it’s tailored to CommonJS, not ES modules.
2. Why Your First Mock Failed
When you wrote this:
const RandomNumber = require.requireActual('../RandomNumber'); RandomNumber.prototype.generate = function() { return this.min; };
RandomNumber wasn’t your class—it was the CommonJS wrapper object for your ES module. This wrapper isn’t a class constructor, so it doesn’t have a prototype property. Trying to set generate on undefined (since RandomNumber.prototype doesn’t exist) threw that TypeError.
Adding .default pulls out the actual class constructor from the wrapper:
const RandomNumber = require.requireActual('../RandomNumber').default; // Now RandomNumber is your class, so prototype is accessible
3. Why jest.genMockFromModule Needs .default Too
The same logic applies here. jest.genMockFromModule processes ES modules the same way, returning that CommonJS wrapper. To get the mockable class, you have to grab the .default property first:
const RandomNumberMock = jest.genMockFromModule('../RandomNumber').default; RandomNumberMock.prototype.generate.mockReturnValue(10);
This is a gotcha from how Node.js handles interop between ES modules and CommonJS. Since many Jest examples stick to CommonJS for simplicity, they don’t cover this ES module-specific edge case.
内容的提问来源于stack exchange,提问作者dragonfly

