测试弹窗逻辑需拦截原生方法(如jest.spyon(window, 'confirm'))、模拟用户交互(mockreturnvalue(true/false))、验证promise封装的resolve/reject及后续业务行为(如api调用、状态更新),并推荐用可注入服务或自定义modal替代原生弹窗以提升可测性。

测试 JavaScript 中弹窗(如 alert、confirm、prompt)的异步确认/取消逻辑,核心在于**拦截原生方法、模拟用户交互、验证后续行为**。由于这些 API 是同步阻塞的,实际项目中常被封装成 Promise 版本(例如 showConfirm()),所以测试重点是这个封装函数的行为是否符合预期。
1. 拦截并模拟 confirm 行为
原生 window.confirm 无法在测试中“点击确定”或“点击取消”,必须用 Jest 或 Vitest 的 jest.spyOn 替换它,并控制返回值:
- 用
jest.spyOn(window, 'confirm').mockReturnValue(true)模拟用户点“确定” - 用
jest.spyOn(window, 'confirm').mockReturnValue(false)模拟用户点“取消” - 测试完记得恢复:
jest.restoreAllMocks()或mockRestore()
2. 测试 Promise 封装函数的 resolve/reject
假设你有如下封装:
function showConfirm(message) {
return new Promise((resolve) => {
const result = window.confirm(message);
resolve(result); // true → 确认,false → 取消
});
}
测试时需验证 Promise 结果和副作用(比如调用接口、更新状态):
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 用
await expect(showConfirm('删除?')).resolves.toBe(true)测试确认路径 - 用
await expect(showConfirm('删除?')).resolves.toBe(false)测试取消路径 - 如果封装中用了
reject(如取消时抛错),则用rejects断言
3. 验证业务逻辑是否按弹窗结果执行
弹窗本身不是目的,关键是它触发的后续动作。例如:
async function handleDelete() {
const confirmed = await showConfirm('确定删除?');
if (confirmed) {
await api.deleteItem();
showToast('已删除');
}
}
测试要点:
- mock
api.deleteItem和showToast - 先 mock
confirm返回true,检查deleteItem是否被调用一次、showToast是否被调用 - 再 mock 返回
false,检查两个函数都未被调用
4. 注意事项与替代方案
直接测 window.confirm 在真实浏览器环境(如 Playwright)里可行,但慢且难调试;单元测试推荐纯 JS 模拟。
- 避免在组件渲染中直接调用
confirm,应提取为可注入的服务,便于 mock - 更现代的做法是用自定义 Modal 组件代替原生弹窗,这样可完全控制状态、支持 await,也更容易测试
- 若使用 Vue/React,确保弹窗调用不破坏响应式或渲染周期(比如不在
useEffect或mounted里直接 await confirm)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










