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

如何用Jest与react-testing-library测试React WebSocket客户端?

没问题,用jest-websocket-mock完全可以实现只模拟WebSocket服务器、让真实客户端组件连接的测试方案,不需要额外mock客户端的WebSocket实例。下面是具体的实现步骤和测试代码:

步骤1:安装依赖

首先确保你已经安装了jest-websocket-mock:

npm install --save-dev jest-websocket-mock

步骤2:编写测试用例

假设你的测试文件是LiveChat.test.jsx,我们可以这样写测试逻辑:

import React from 'react';
import { render, waitFor } from '@testing-library/react';
import MockServer from 'jest-websocket-mock';
import LiveChat from './LiveChat';

// 替换成你实际项目中TEXT常量的定义
const TEXT = 'text';

describe('LiveChat WebSocket Message Handling', () => {
  let mockWsServer;

  beforeEach(() => {
    // 创建一个mock服务器,使用组件中硬编码的WebSocket地址
    mockWsServer = new MockServer('ws://localhost:1234');
    // Mock全局的alert函数,方便我们断言它的调用情况
    window.alert = jest.fn();
    // 如果你的playChatMessageSound函数需要测试,也可以在这里mock它
    // jest.mock('./utils/sound', () => ({ playChatMessageSound: jest.fn() }));
  });

  afterEach(() => {
    // 清理mock服务器和所有jest mock
    MockServer.clean();
    jest.restoreAllMocks();
  });

  it('triggers alert with correct content when receiving TEXT type message', async () => {
    // 渲染LiveChat组件,它会自动尝试连接到我们创建的mock服务器
    render(<LiveChat />);

    // 等待组件和mock服务器建立连接
    await mockWsServer.connected;

    // 模拟服务器向客户端发送TEXT类型的消息
    const testPayload = {
      messageContent: 'Hi there! This is a test message.',
      messageType: TEXT,
      secureKey: 'test-secure-key'
    };
    mockWsServer.send(JSON.stringify(testPayload));

    // 等待alert被调用,并断言它的参数是否正确
    await waitFor(() => {
      expect(window.alert).toHaveBeenCalledWith('Hi there! This is a test message.');
      // 如果mock了playChatMessageSound,也可以加这句断言
      // expect(playChatMessageSound).toHaveBeenCalled();
    });
  });
});

关键说明

  1. 不需要mock客户端WebSocket:这里我们没有修改组件里的new WebSocket()逻辑,jest-websocket-mock会自动拦截指向目标地址的WebSocket连接,让组件连接到我们的mock服务器,完全保留客户端的真实行为。
  2. 等待连接建立:用await mockWsServer.connected确保组件已经和mock服务器完成握手,避免发送消息时组件还没连接上。
  3. Mock全局alert:因为浏览器的alert会阻塞测试,所以我们用jest mock替换它,方便后续断言。

可选优化:让WebSocket地址可配置

如果不想依赖硬编码的WebSocket地址,可以把地址改成组件的props,这样测试时更灵活:

// 修改LiveChat组件
const LiveChat = ({ wsUrl = 'ws://localhost:1234' }) => { 
  const [socket, setSocket] = useState(null) 
  useEffect(() => { 
    setSocket(new WebSocket(wsUrl)) 
  }, [wsUrl]) 
  // 其余代码不变
}

然后测试时传入mock服务器的地址:

render(<LiveChat wsUrl={mockWsServer.url} />);

这样不管mock服务器用什么地址,组件都能正确连接,不需要和硬编码地址强绑定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:00:51