mock import() 失败需拦截模块加载并让 promise 拒绝:jest 中用 jest.mock() 配合 mockrejectedvalue;非 jest 环境可覆盖 globalthis.import;注意路径匹配、esm 限制及推荐网络层拦截。

在 JavaScript 单元测试中,Mock import() 失败(即动态导入抛出异常)的关键是拦截模块加载过程,并让 Promise 拒绝。由于 import() 返回的是原生 Promise,不能直接用普通函数替换,需借助测试框架能力或运行时劫持。
使用 Jest 的 jest.mock() 模拟失败
Jest 支持对动态导入目标模块进行自动 mock,但要触发“失败”,需在 mock 实现中主动 throw 错误:
- 确保被 import 的模块路径可被 Jest 识别(如相对路径或已配置的别名)
- 调用
jest.mock('./module')后,用jest.mocked(...).mockRejectedValue(...)让其返回拒绝的 Promise - 注意:必须在
import()调用前完成 mock,推荐放在beforeEach或测试顶部
示例:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
// utils.js
export const loadData = async () => {
try {
const mod = await import('./heavy-module');
return mod.default();
} catch (err) {
return 'fallback';
}
};
// utils.test.js
import { loadData } from './utils';
// Mock 模块本身(路径必须和 import() 中一致)
jest.mock('./heavy-module');
test('import() 失败时返回 fallback', async () => {
// 让 mock 模块的默认导出 Promise 拒绝
const mockImport = jest.requireActual('./heavy-module');
jest.mocked(import('./heavy-module')).mockRejectedValue(new Error('Network failed'));
const result = await loadData();
expect(result).toBe('fallback');
});
手动替换 globalThis.import(适用于非 Jest 环境)
在 Vitest、JSDOM 或自定义测试环境里,可临时覆盖全局 import 函数:
- 保存原始
import供后续恢复 - 用
vi.fn()(Vitest)或jest.fn()替换,返回Promise.reject(...) - 注意:该方式会影响所有
import(),建议只在单个测试中作用域内修改并清理
Vitest 示例:
test('import fails with network error', async () => {
const originalImport = globalThis.import;
globalThis.import = vi.fn().mockRejectedValue(new TypeError('Failed to fetch'));
await expect(async () => {
await import('./missing.js');
}).rejects.toThrow('Failed to fetch');
// 恢复原始 import(可选,vi.resetMocks() 通常已处理)
globalThis.import = originalImport;
});
避免常见陷阱
-
路径必须完全匹配:
jest.mock('./a')不会拦截import('./a.js')(.js 后缀影响解析) -
不能 mock 未声明的模块:若
import()路径含变量(如import(`./${name}.js`)),Jest 无法静态分析,需改用全局import替换 -
ESM 环境限制:Node.js 原生 ESM 不允许重写
import,此时只能通过构建时插件(如 vite-plugin-mock-import)或改用 CommonJS 测试环境
真实错误场景更推荐用网络层拦截
如果目标是模拟“网络请求失败”这类底层原因,比直接 mock import() 更合理的方式是:
- 用
msw(Mock Service Worker)拦截对 chunk 文件的 HTTP 请求,返回 404 或超时 - 或在测试启动时伪造
fetch,匹配.js请求并 reject - 这样能覆盖真实加载链路,包括 webpack/vite 的 runtime 加载逻辑
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










