javascript测试富文本图片上传进度的核心是模拟上传、捕获进度事件、验证回调逻辑:需覆盖0%→100%逐次更新、错误处理、完成插入,结合jest mock事件与playwright验证ui反馈。

在 JavaScript 中测试富文本编辑器中图片上传的异步进度,核心是**模拟真实上传行为、捕获进度事件、验证回调逻辑是否按预期触发**。不能只测“有没有调用 upload 函数”,而要验证:进度是否逐次更新、是否能正确响应 0% → 50% → 100%、错误时是否抛出/捕获、完成时是否插入 DOM 或返回正确结果。
一、确保上传逻辑暴露可监听的进度事件
富文本编辑器(如 Quill、Tiptap、WangEditor)通常封装了图片上传,但你需要让上传过程支持 XMLHttpRequest.upload.onprogress 或 fetch + ReadableStream 的进度读取。若使用第三方 SDK(如七牛、阿里 OSS),确认其上传方法返回含 onUploadProgress 的 Promise 或支持传入 progress 回调。
示例(手动封装 FormData 上传):
function uploadImage(file) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/upload');
xhr.upload.onprogress = (e) => {
if (e.lengthComputable) {
const percent = Math.round((e.loaded / e.total) * 100);
// 触发自定义进度事件,便于测试捕获
document.dispatchEvent(new CustomEvent('imageUploadProgress', { detail: { percent } }));
}
};
xhr.onload = () => resolve(xhr.response);
xhr.onerror = reject;
const fd = new FormData();
fd.append('image', file);
xhr.send(fd);
});
}二、用 Jest + Mock 实现进度事件的可控触发
不依赖真实网络请求,而是 mock XHR 或直接 dispatch 自定义进度事件,再监听并断言。
- 用
jest.mock('path-to-upload-util')拦截上传函数,返回一个可控制 resolve/reject 和中间 dispatch 的 Promise - 在测试中监听
imageUploadProgress事件,用jest.fn()记录每次触发的百分比 - 用
await waitFor(() => expect(progressMock).toHaveBeenCalledWith(75))验证中间进度
关键代码片段:
test('富文本图片上传应正确报告 0% → 100% 进度', async () => {
const progressMock = jest.fn();
document.addEventListener('imageUploadProgress', (e) => progressMock(e.detail.percent));
<p>// mock uploadImage 返回一个可控制进度的 Promise<br>
jest.mock('./upload', () => ({<br>
uploadImage: jest.fn().mockImplementation(() => {<br>
// 模拟分阶段 dispatch<br>
setTimeout(() => document.dispatchEvent(new CustomEvent('imageUploadProgress', { detail: { percent: 30 } })), 10);<br>
setTimeout(() => document.dispatchEvent(new CustomEvent('imageUploadProgress', { detail: { percent: 70 } })), 30);<br>
setTimeout(() => document.dispatchEvent(new CustomEvent('imageUploadProgress', { detail: { percent: 100 } })), 60);<br>
return Promise.resolve({ url: '<a href="https://www.php.cn/link/86bef77c5a59d7f1195cb2fbe242882d">https://www.php.cn/link/86bef77c5a59d7f1195cb2fbe242882d</a>' });<br>
})<br>
})); </p><p>// 触发富文本粘贴/插入图片(例如调用 editor.insertEmbed)<br>
await insertImageToEditor(file); </p><p>await waitFor(() => expect(progressMock).toHaveBeenCalledWith(30));<br>
await waitFor(() => expect(progressMock).toHaveBeenCalledWith(70));<br>
await waitFor(() => expect(progressMock).toHaveBeenCalledWith(100));<br>
expect(progressMock).toHaveBeenCalledTimes(3);<br>
});</p>三、测试边界情况:中断、超时、失败重试
真实场景中,用户可能取消上传、网络闪断、服务返回 400/500。测试需覆盖:
- 上传中途调用
xhr.abort()后,是否触发uploadAbort事件或清除 UI 加载态 - 模拟 fetch 超时(用
jest.setTimeout+Promise.race)后,是否显示错误提示且不卡死编辑器 - 上传失败后点击“重试”,是否重新触发完整流程(包括从 0% 开始)
技巧:用 jest.useFakeTimers() 精确控制异步节奏,避免测试不稳定。
四、端到端补充:用 Playwright/Cypress 验证 UI 反馈
单元测试验证逻辑,E2E 测试验证用户看到的进度条、百分比文案、禁用按钮等是否同步更新:
- 上传开始 → 检查进度条是否 visible、按钮是否 disabled
- 监听
console.log或自定义 log 事件(开发环境注入)确认进度值被打印 - 截图比对不同进度阶段的 UI 快照(如 0%、50%、100%)
Playwright 示例:
await test.step('上传中显示 65% 进度', async () => {
await page.setInputFiles('input[type="file"]', imageFile);
await expect(page.locator('.progress-bar')).toBeVisible();
await expect(page.locator('.progress-text')).toHaveText('65%');
});Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











