测试 WebSocket 模块需用 mock-socket 替换全局 WebSocket 对象,模拟连接、状态切换、消息收发、错误处理及重连逻辑,确保异步行为可断言、可清理、可重复。

测试依赖 WebSocket 的实时消息模块,关键不是绕开连接,而是用可控的模拟服务替代真实网络,把异步通信变成可断言、可清理、可重复的测试流程。
用 mock-socket 拦截并接管 WebSocket 实例
不能靠拦截 fetch 或 mock URL,因为 new WebSocket() 是独立于 HTTP 栈的底层构造。必须替换全局 WebSocket 对象本身:
- 安装:
npm install mock-socket --save-dev - 在测试入口(如
setupTests.js)中初始化模拟服务器:import { Server } from 'mock-socket';<br>const server = new Server('ws://localhost:8080'); - 业务代码保持原样,仍调用
new WebSocket('ws://localhost:8080'),无需修改 - 每个测试结束后调用
server.close(),避免连接残留和状态污染
覆盖连接生命周期与关键状态转换
真实场景中,bug 多发生在状态切换的“间隙”,比如连接未就绪时发消息、服务端提前推送等:
- 验证
readyState === CONNECTING时调用send():消息应自动排队,待变为OPEN后发出 - 在
server.on('connection', socket => { socket.send('hi'); })中立即发消息,检查客户端是否能在onopen执行前收到onmessage - 主动触发关闭:
socket.close(4001, 'Network error'),断言客户端onclose的code和reason是否匹配 - 发送非法数据(如空 ArrayBuffer)触发
onerror,确认错误处理逻辑被调用
验证消息收发与数据完整性
不只是“有没有收到”,还要确保内容、顺序、序列化行为符合预期:
立即学习“Java免费学习笔记(深入)”;
- 发送字符串、数字、嵌套对象,检查
lastMessage.data是否完整还原(注意结构化克隆限制) - 连续发多条消息(如
'Hello'、'There'、'Friend'),验证lastMessage只保留最新一条,且历史不丢失(若模块维护队列) - 使用
jest.fn()绑定onmessage,再通过await waitFor(() => expect(handler).toHaveBeenCalledTimes(1))等待异步完成 - 测试 JSON 序列化/反序列化环节:发送对象后,检查接收端解析结果是否与原始一致
集成到 React Hook 测试中(如 useWebSocket)
若模块封装为自定义 Hook,需结合 @testing-library/react-hooks 验证响应式行为:
- 渲染 Hook 并监听
result.current.lastMessage和readyState - 调用
server.connected等待连接建立,再用server.send()推送消息 - 断言
result.current.lastMessage?.data在异步后更新为预期值 - 测试重连逻辑:
server.close()后观察readyState是否按配置尝试恢复


















