单元测试微前端沙箱隔离需聚焦行为边界:验证拦截修改、卸载还原、多沙箱互斥三类场景,覆盖生命周期各阶段;须 mock 全局副作用 API;区分 Proxy/快照/iframe 沙箱机制设计断言;规避状态残留、异步遗漏、原型链误判等陷阱。

单元测试微前端沙箱隔离,核心是验证沙箱能否真实拦截、隔离、还原对 window 等全局对象的修改,且不干扰其他沙箱或主应用环境。不能只测“代码跑通”,而要聚焦行为边界:改了什么、是否被拦截、卸载后是否干净、多沙箱是否互不污染。
重点覆盖三类断言场景
测试用例应围绕沙箱生命周期(激活 → 运行 → 失活)设计,每类场景需有明确的预期行为:
-
写隔离验证:子应用执行
window.foo = 'a'后,真实window.foo不应存在或值不变;读取时应返回代理值(Proxy 沙箱)或抛出未定义(快照沙箱失活后) -
状态还原验证:沙箱失活后,检查
window上新增属性是否被删除、被覆盖的原属性是否恢复原值(如window.console被重写后是否回滚) -
多实例互斥验证:同时创建沙箱 A 和 B,A 设置
window.a = 1,B 设置window.b = 2,分别失活后再检查彼此属性是否残留、是否影响对方状态
Mock 全局副作用 API 是关键前提
沙箱常需拦截 addEventListener、fetch、setTimeout 等可能泄漏的 API。单元测试中必须提前 mock 它们,否则测试会受真实浏览器行为干扰:
- 用
jest.mock('whatwg-fetch')或global.fetch = jest.fn()拦截网络请求 - 重写
global.addEventListener = jest.fn()并在测试后clearMocks - 对
document.createElement等 DOM 操作做 shallow mock,避免真实插入节点
区分沙箱类型编写针对性用例
不同沙箱机制需不同断言逻辑,不可一套用例通吃:
立即学习“Java免费学习笔记(深入)”;
-
Proxy 沙箱:验证
proxyWindow是否正确代理读写,检查Reflect.get(proxy, 'xxx')是否走 handler;测试proxy.location是否返回window.location,但proxy.foo = 1不影响window.foo -
快照沙箱:重点测
activate()前后window属性枚举差异,用Object.keys(window)对比快照前后数量与键名;验证deactivate()是否精准还原(包括删除新增 key、重置被改值) -
iframe 沙箱:测试需在 iframe contentWindow 中执行,验证其
window.top是否为 null、window.parent是否受限;检查 postMessage 通信是否唯一出口
避免常见测试陷阱
很多测试看似通过,实则没打中要害:
- 不重置
window状态就连续跑多个用例 → 用afterEach(() => { jest.resetModules(); })或手动清理新增属性 - 只测同步赋值,忽略异步回调(如
setTimeout(() => window.flag = true))→ 必须 await 或用jest.runAllTimers() - 用
expect(window.foo).toBeUndefined()但未考虑原型链污染 → 改用Object.prototype.hasOwnProperty.call(window, 'foo')确认是否真新增 - 忽略函数引用泄漏:子应用保存了
window.console.log引用,卸载后仍可调用 → 需在失活时遍历清理绑定的函数引用


















