javascript单元测试中伪造剪贴板操作需mock navigator.clipboard的writetext/readtext方法并返回promise,推荐用mockresolvedvalue/mockrejectedvalue;同时可mock permissions.query以覆盖权限场景,注意用object.assign赋值、清理mock及处理clipboardevent监听。

在 JavaScript 单元测试中伪造剪贴板操作,核心是**替换或模拟 navigator.clipboard API 的方法(如 writeText、readText)**,避免真实触发系统剪贴板(既不可靠,又可能污染环境或引发权限问题)。主流测试框架(Jest、Vitest)都支持通过 jest.mock 或 vi.mock 实现,关键在于正确 mock 全局对象并控制返回行为。
1. 基础 Mock:覆盖 navigator.clipboard 方法
直接在测试文件顶部或 beforeEach 中 mock navigator.clipboard,使其返回一个带可控 resolve/reject 行为的模拟对象:
- 用
jest.fn()或vi.fn()创建可断言的 mock 函数 -
writeText和readText必须返回 Promise,否则调用会报错(原生 API 是异步的) - 推荐使用
mockResolvedValue模拟成功,mockRejectedValue模拟拒绝(如权限被拒)
示例(Jest):
beforeEach(() => {
Object.assign(navigator, {
clipboard: {
writeText: jest.fn().mockResolvedValue(),
readText: jest.fn().mockResolvedValue('mocked content'),
},
});
});
2. 处理权限检查:mock Permissions API(可选但推荐)
某些代码会在调用剪贴板前检查权限(navigator.permissions.query({ name: 'clipboard-write' })),这时需一并 mock navigator.permissions:
- 返回一个带
state('granted' / 'denied' / 'prompt')的 mock PermissionStatus 对象 -
query方法返回一个解析该状态的 Promise
示例:
Object.assign(navigator, {
permissions: {
query: jest.fn().mockResolvedValue({ state: 'granted' }),
},
clipboard: { /* ... */ }
});
3. 测试不同场景:成功、失败、边缘情况
不要只测“能写入”,要覆盖真实用户可能遇到的情况:
-
成功复制:验证
writeText被调用且参数正确,组件状态更新(如显示“已复制”提示) -
复制失败:mock
writeText拒绝,检查错误处理逻辑(如捕获异常、显示错误 toast) -
无权限:mock
permissions.query返回'denied',验证降级逻辑(如 fallback 到document.execCommand或提示手动复制) -
空内容:传入空字符串或
null,确认函数不崩溃且有合理响应
4. 注意事项与常见坑
实际使用中容易忽略的细节:
-
不能直接赋值
navigator.clipboard = {...}——navigator.clipboard是只读属性,必须用Object.assign或Object.defineProperty配合writable: true - 测试结束后建议
jest.clearAllMocks()或重置navigator.clipboard,避免影响其他测试 - Vitest 用户注意:需启用
globals: true并确保setupFiles正确加载,否则navigator可能为undefined - 若组件依赖
ClipboardEvent(如监听粘贴),需额外 mockdocument.addEventListener('paste', ...)并手动触发事件
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











