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

使用Jest测试Socket.io房间控制器时出现假阳性问题求助

Fixing Your Jest/Socket.io Test False Positive Issue

Let's break down why your test is giving false positives and fix it step by step:

Key Issues in Your Current Test

  1. Incorrect await usage on serverSocket.on: The on method registers an event listener—it doesn't return a promise, so await here does nothing and leads to timing issues.
  2. Un-triggered client emit callback: Your server never responds to the client's emit callback, so the expect inside that callback never runs (which is why expect.assertions(1) made it fail, correctly indicating the assertion wasn't executed).
  3. Calling a method as a property: expect(roomController.getRoomCount).toEqual(2) checks the method reference instead of invoking it—you need getRoomCount().

Corrected Test Code

import { RoomController } from '../../controllers/roomController';
const { createServer } = require("http");
const { Server } = require("socket.io");
const Client = require("socket.io-client");

jest.setTimeout(30000);

describe("The room controller", () => {
  const roomController = new RoomController();
  let io: any, serverSocket: any, clientSocket: any;

  beforeAll((done) => {
    const httpServer = createServer();
    io = new Server(httpServer);
    httpServer.listen(() => {
      const port = httpServer.address().port;
      clientSocket = new Client(`http://localhost:${port}`);
      io.on("connection", (socket: any) => {
        serverSocket = socket;
        // Register the event listener here (no await needed)
        serverSocket.on("test_event", (callback?: () => void) => {
          roomController.addRoom(serverSocket);
          // Trigger the client's callback if provided
          if (callback) callback();
        });
      });
      clientSocket.on("connect", done);
    });
  });

  afterAll(() => {
    io.close();
    clientSocket.close();
  });

  test('should correctly display the number of rooms', async () => {
    expect.assertions(1); // Ensures our assertion runs

    // Wrap emit calls in promises to wait for server processing
    const emitTestEvent = () => new Promise(resolve => {
      clientSocket.emit('test_event', resolve);
    });

    // Trigger two room creations, waiting for each to complete
    await emitTestEvent();
    await emitTestEvent();

    // Now assert the room count
    expect(roomController.getRoomCount()).toEqual(2);
  });
});

What Changed & Why

  • Moved event listener registration to beforeAll: We register the test_event handler when the server socket connects, so it's ready before tests run—no need for await here.
  • Added callback triggering in server handler: The server now calls the client's callback after adding the room, letting us wait for the operation to finish.
  • Wrapped emit in promises: This lets us use await to ensure each room is created before moving to the next step, eliminating race conditions.
  • Fixed getRoomCount() call: We now invoke the method instead of checking the reference.
  • Kept expect.assertions(1): This guards against false positives by ensuring our assertion actually executes.

Bonus: TypeScript Improvements

To fix those any types (you were right to note they're not ideal), you can import the proper Socket.io types:

import { Server, Socket } from 'socket.io';
import { Socket as ClientSocket } from 'socket.io-client';

// Then update your variables:
let io: Server, serverSocket: Socket, clientSocket: ClientSocket;

This will give you proper type checking and autocomplete for Socket.io methods.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 02:07:46