You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular单元测试:如何测试创建WebSocket的服务

单元测试实现思路与代码示例

你需要先Mock rxjs/webSocket 导出的webSocket工厂函数,避免测试时发起真实的WebSocket连接,同时方便捕获调用行为和模拟返回结果。另外需要处理测试中的定时器逻辑,跳过delay(1000)的实际等待时间。


1. 测试用例1:校验WebSocket是否被正确创建

你之前的断言思路有误,getSomething返回的是封装后的Observable流,不会直接返回WebSocket实例,正确的断言应该是验证webSocket工厂函数被调用,且传入的连接地址符合预期。

示例代码(以Jest为例,Jasmine写法逻辑一致):

import { webSocket } from 'rxjs/webSocket';

// 首先Mock webSocket函数
jest.mock('rxjs/webSocket', () => ({
  ...jest.requireActual('rxjs/webSocket'),
  webSocket: jest.fn(() => new Observable()), // 先返回空的Observable避免报错
}));

it('should create websocket when calling getSomething', () => {
  service.getSomething('test').subscribe();
  // 断言webSocket被调用,且参数为正确的地址
  expect(webSocket).toHaveBeenCalledWith('ws://<websocket>');
  expect(webSocket).toHaveBeenCalledTimes(1);
});

2. 测试用例2:模拟WebSocket连接错误,验证错误处理逻辑

这个用例需要让Mock的webSocket返回抛出错误的Observable,同时用fakeAsync处理定时器,验证错误捕获、null值下发、重试逻辑是否符合预期。

示例代码:

import { throwError, of } from 'rxjs';
import { fakeAsync, tick } from '@angular/core/testing'; // 非Angular项目可替换为对应测试工具的定时器mock

it('should handle websocket connection error correctly', fakeAsync(() => {
  // 捕获console.error调用,验证错误日志输出
  const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
  const mockError = new Error('WebSocket connect failed');
  // 让mock的webSocket返回抛出错误的流
  (webSocket as jest.Mock).mockReturnValue(throwError(() => mockError));

  const emittedValues: (State|null)[] = [];
  let receivedError: Error | null = null;

  service.getSomething('test').subscribe({
    next: (val) => emittedValues.push(val),
    error: (err) => receivedError = err,
  });

  // 第一次错误触发,先验证catchError返回了null
  expect(emittedValues).toEqual([null]);
  // 验证错误日志被打印
  expect(consoleErrorSpy).toHaveBeenCalledWith('Error in WebSocket connection: ', mockError);

  // 跳过1秒等待,触发retryWhen的重试逻辑
  tick(1000);
  // 验证webSocket因为重试被调用了第二次
  expect(webSocket).toHaveBeenCalledTimes(2);

  // 清理spy
  consoleErrorSpy.mockRestore();
}));

补充说明

  • 如果你的测试工具不支持fakeAsync,可以用done回调结合RxJS的测试调度器来处理延迟逻辑
  • 可以额外添加断言验证重试次数符合预期,比如多次触发tick查看webSocket的调用次数

内容的提问来源于stack exchange,提问作者Tom Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 01:15:07