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

如何在Puppeteer中Mock WebSocket通信?

Great question! Testing WebSocket interactions without a real backend is totally doable—here are the methods I’ve used successfully in projects, depending on how close you want the test to mimic real behavior:


1. Manually Mock the WebSocket API

For straightforward tests where you just need to trigger specific events, creating a mock WebSocket class is simple and gives you full control. You can simulate connection opens, incoming messages, closures, and even track outgoing messages for assertions.

Here’s a basic implementation you can drop into your test setup:

class MockWebSocket {
  constructor(url) {
    this.url = url;
    this.onopen = null;
    this.onmessage = null;
    this.onclose = null;
    this.onerror = null;
    
    // Simulate a delayed connection open (matches real WebSocket behavior)
    setTimeout(() => {
      if (this.onopen) this.onopen({ type: 'open' });
    }, 100);
  }

  send(data) {
    // Track sent messages so you can verify your app is sending the right stuff
    console.log('Mock WebSocket sent:', data);
    // Or store in an array for later assertions:
    // MockWebSocket.sentMessages.push(data);
  }

  // Helper to simulate server sending a message to the client
  triggerMessage(messageData) {
    if (this.onmessage) {
      this.onmessage({
        type: 'message',
        data: JSON.stringify(messageData) // Adjust format to match your app's expectations
      });
    }
  }

  // Helper to trigger a close event
  triggerClose(code = 1000, reason = 'Normal closure') {
    if (this.onclose) {
      this.onclose({ type: 'close', code, reason });
    }
  }
}

// Replace the global WebSocket with your mock before running tests
global.WebSocket = MockWebSocket;

In your test, you’d initialize your app, grab the mock WebSocket instance, and trigger events to see how your app reacts:

test('app displays notification on WebSocket message', () => {
  // Initialize your app (which creates a WebSocket connection)
  initMyApp();

  // Get the mock WebSocket instance (adjust based on how your app stores it)
  const socket = global.WebSocket.instances[0];

  // Simulate the server sending a notification
  socket.triggerMessage({ type: 'alert', text: 'New update available!' });

  // Assert your app updated correctly (e.g., check the DOM)
  expect(document.querySelector('.alert-banner').textContent).toBe('New update available!');
});

2. Use Your Testing Framework’s Mocking Tools

If you’re using Jest, Vitest, or another framework with built-in mocking, you can spy on or mock the WebSocket API directly without writing a full class. This is great for quick, focused tests.

Example with Jest:

describe('WebSocket behavior', () => {
  let mockSocket;
  let mockOnMessageCallback;

  beforeEach(() => {
    // Create a mock socket object with the methods your app uses
    mockOnMessageCallback = jest.fn();
    mockSocket = {
      onopen: jest.fn(),
      onmessage: mockOnMessageCallback,
      onclose: jest.fn(),
      send: jest.fn(),
      // Add a helper to trigger incoming messages
      simulateMessage: (data) => {
        mockOnMessageCallback({ data: JSON.stringify(data) });
      }
    };

    // Mock the global WebSocket to return our mock socket
    global.WebSocket = jest.fn(() => mockSocket);
  });

  afterEach(() => {
    // Clean up mocks after each test
    jest.restoreAllMocks();
  });

  test('app sends a message when user clicks "Send"', () => {
    initMyApp();

    // Simulate user action that triggers a WebSocket send
    document.querySelector('#send-btn').click();

    // Assert the app sent the correct message
    expect(mockSocket.send).toHaveBeenCalledWith(JSON.stringify({ action: 'user_message', text: 'Hello server!' }));
  });

  test('app updates state on incoming message', () => {
    initMyApp();

    // Simulate server sending data
    mockSocket.simulateMessage({ type: 'chat', user: 'Bot', message: 'Hi there!' });

    // Assert your app's state or UI changed (adjust based on your framework)
    expect(document.querySelector('.chat-message').textContent).toBe('Bot: Hi there!');
  });
});

3. Use a Lightweight Mock WebSocket Server

For more end-to-end-like tests where you want to simulate real back-and-forth communication, use a mock server library. These let you define how the "server" responds to incoming messages, which is perfect for testing complex flows like request-response cycles.

Here’s how you might use one (install via npm/yarn first):

import { Server } from 'mock-socket';

describe('Full WebSocket flow', () => {
  let mockServer;

  beforeEach(() => {
    // Create a mock server at a fake URL your app connects to
    mockServer = new Server('ws://localhost:9000');

    // Define server behavior: respond to client messages
    mockServer.on('connection', (socket) => {
      socket.on('message', (clientData) => {
        const parsedData = JSON.parse(clientData);
        if (parsedData.action === 'get_status') {
          // Send a response back to the client
          socket.send(JSON.stringify({ status: 'online', users: 5 }));
        }
      });
    });
  });

  afterEach(() => {
    // Close the mock server after each test
    mockServer.close();
  });

  test('app fetches and displays server status', async () => {
    initMyApp(); // App connects to ws://localhost:9000

    // Wait for the connection to establish
    await new Promise(resolve => mockServer.on('connection', resolve));

    // Trigger the app to request status
    document.querySelector('#check-status').click();

    // Wait for the response to be processed
    await new Promise(resolve => setTimeout(resolve, 150));

    // Assert the UI shows the correct status
    expect(document.querySelector('.status-text').textContent).toBe('Online (5 users)');
  });
});

Pro Tips:

  • Test edge cases: Don’t forget to simulate connection errors, invalid message formats, or unexpected closures to make sure your app handles them gracefully.
  • Framework-specific tweaks: If you’re using React, Vue, or Angular, pair these methods with your framework’s testing tools (like React Testing Library) to assert component state changes instead of just DOM elements.
  • Avoid hardcoding URLs: Make sure your app uses a configurable WebSocket URL so you can easily point it to your mock server in tests.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:40:27