使用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
- Incorrect
awaitusage onserverSocket.on: Theonmethod registers an event listener—it doesn't return a promise, soawaithere does nothing and leads to timing issues. - Un-triggered client emit callback: Your server never responds to the client's emit callback, so the
expectinside that callback never runs (which is whyexpect.assertions(1)made it fail, correctly indicating the assertion wasn't executed). - Calling a method as a property:
expect(roomController.getRoomCount).toEqual(2)checks the method reference instead of invoking it—you needgetRoomCount().
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 thetest_eventhandler when the server socket connects, so it's ready before tests run—no need forawaithere. - 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
emitin promises: This lets us useawaitto 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
相关产品推荐
相关产品推荐

