_generateMock(from, moduleName) {
const modulePath =
this._resolver.resolveStubModuleName(from, moduleName) ||
this._resolveModule(from, moduleName, {
conditions: this.cjsConditions
});
if (!this._mockMetaDataCache.has(modulePath)) {
// This allows us to handle circular dependencies while generating an
// automock
this._mockMetaDataCache.set(
modulePath,
this._moduleMocker.getMetadata({}) || {}
); // In order to avoid it being possible for automocking to potentially
// cause side-effects within the module environment, we need to execute
// the module in isolation. This could cause issues if the module being
// mocked has calls into side-effectful APIs on another module.
const origMockRegistry = this._mockRegistry;
const origModuleRegistry = this._moduleRegistry;
this._mockRegistry = new Map();
this._moduleRegistry = new Map();
const moduleExports = this.requireModule(from, moduleName); // Restore the "real" module/mock registries
this._mockRegistry = origMockRegistry;
this._moduleRegistry = origModuleRegistry;
const mockMetadata = this._moduleMocker.getMetadata(moduleExports);
if (mockMetadata == null) {
throw new Error(
`Failed to get mock metadata: ${modulePath}\n\n` +
'See: https://jestjs.io/docs/manual-mocks#content'
);
}
this._mockMetaDataCache.set(modulePath, mockMetadata);
}
2条答案
按热度按时间g6baxovj1#
这让我犯了好几次错。
如果你没有为
jest.mock
提供一个mock实现,它将返回一个对象,该对象镜像了mocked模块的导出,但每个函数都被mockjest.fn()
替换。这是相当整洁的,因为它往往是你想要的。但是为了确定模块的导出,它必须先require
它。这就是导致console.log
运行的原因。两种可能的解决方案:
jest.mock('./foo', () => {})
brc7rcf02#
Jest仍然执行自动锁的模块,因为这就是自动锁的工作方式。
它尝试执行模块脚本并分析结果对象属性,而不是静态代码分析。
结果对象属性(通常是函数)被用作“蓝图”,以创建具有相同属性但具有模拟值的模拟模块。
看看Jest的模拟生成代码:
在这段代码中,'真实的'模块代码将在线执行
正如Tamlyn的回答中所提到的,可以通过手动模拟实现来避免自动锁。