Java单元测试WebSocket客户端应不依赖真实服务器,通过内存模拟服务器(如Java-WebSocket的WebSocketServer)或Mockito模拟连接行为,覆盖正常握手、拒绝连接、超时、非法URI等场景,并可验证自定义握手头字段。

Java 单元测试 WebSocket 客户端连接,核心是**不依赖真实服务器、不启动网络端口、快速验证连接逻辑与异常路径**。重点不是“连上远端”,而是验证客户端类在各种输入和状态下的行为是否符合预期。
用内存模拟服务器(推荐)
借助 Java-WebSocket 库自带的 WebSocketServer 本地实例,在测试中启动一个轻量级、自动释放的服务器:
- 调用 SocketUtil.getAvailablePort() 获取临时空闲端口,避免端口冲突
- 继承 WebSocketServer,重写
onOpen、onMessage等方法,控制响应逻辑(例如:收到特定消息就主动关闭,用于测异常断开) - 在
@BeforeEach中启动服务器,在@AfterEach中调用stop()并等待关闭完成 - 客户端用
new MyWebSocketClient(URI.create("ws://localhost:" + port))连接,全程走本地回环,毫秒级完成
隔离网络层,专注逻辑验证
对客户端类做依赖抽象,把底层连接能力抽成接口(如 WebSocketConnector),测试时用 Mockito 模拟:
- Mock
connect()方法,让它立即回调onOpen或抛出IOException - Mock
send()行为,验证是否按预期调用了发送逻辑,而不是真发出去 - 验证重连策略:当第一次
connect()失败后,是否在指定延迟后触发第二次调用
覆盖关键连接场景
每个测试用例聚焦一个明确目标,避免“一测多验”:
-
正常握手成功:检查
onOpen是否被调用、Session是否非空、连接状态是否变为 OPEN -
服务端拒绝连接(HTTP 401/403):验证是否触发
onError而非onClose,且异常类型匹配 - 超时未响应:设置短超时(如 500ms),确认是否在时限内抛出超时异常并进入错误处理流程
-
非法 URI 格式:传入
"ws://"或含空格的地址,检查构造函数或connect()是否提前抛出IllegalArgumentException
验证握手细节(可选但重要)
若客户端需支持自定义头、Token 注入或协议协商,测试应深入握手请求本身:
- 通过反射获取客户端内部的
handshakeBuilder或类似字段 - 检查是否设置了
Sec-WebSocket-Protocol、Authorization等头字段 - 验证
Sec-WebSocket-Key是否为随机生成且 Base64 编码(无需校验服务端 Accept 值,那是服务端职责)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











