【问题标题】:Jest with socket.io test passing false positive开玩笑,socket.io 测试通过误报
【发布时间】:2021-11-09 16:03:41
【问题描述】:

我正在开发一个小型回合制多人游戏项目,该项目在前端使用 React,在后端使用带有 socket.io 的 node.js,全部使用 typescript。目前,我正在研究创建和加入房间(类似于 jackbox.tv)的逻辑,并为房间控制器类编写单元测试。在我的代码中,房间只是一个类,它可以存储与前端单个用户相对应的多个套接字实例。这个 roomController 类的方法之一返回已创建的房间数。我想编写一个创建两个房间的测试,然后检查此函数是否返回正确的房间数。

我在 beforeAll 和 afterAll 钩子中设置了服务器和客户端套接字,然后在我的测试中,我为“test_event”设置了一个服务器端 eventListener,它将在收到时添加一个新房间,然后从客户端我发出两个这些事件并使用第二个回调来做出断言。我使用了异步等待,因为我只想在服务器实际收到两个事件后才做出断言。如果我要发出 15 个事件,我预计应该有 15 个新房间。

目前,无论.toEqual() 的值如何,测试都作为误报通过。我不确定问题在于我对 Jest 的使用,还是来自 socket.io .emit() 方法的回调不起作用。

编辑:在 Jest 文档中发现 expect.assertions(1);。添加这个会导致测试失败,我可以看到期望没有在发出方法的回调中运行。

import { doesNotMatch } from 'assert';
import Jest from 'jest';
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; //usage of any here probably not a good use of typescript

    //see example on socket.io testing documentation page
    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;        
            });
            clientSocket.on("connect",done)
        })
    });

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

    test('should correctly display the number of rooms',async()=>{
        await serverSocket.on("test_event", ()=>{
            roomController.addRoom(serverSocket);
        });
        await clientSocket.emit('test_event');
        await clientSocket.emit('test_event',(response)=>{
            expect(roomController.getRoomCount).toEqual(2);
        });
    });
    
})    

供参考我的房间模型类:

/**
 * @class Model
 *
 * Manages the data of a room.
 */

import {Socket} from 'socket.io';
import randomstring from "randomstring";

export class Room {
    public roomId: string = '';
    public players: Map<string,Socket> = new Map();
    public gameStarted: boolean = false;
    
    constructor(
        callingPlayer:Socket
    ){
        this.addPlayer(callingPlayer);
        this.generateRoomCode();
    }

    private addPlayer(player:Socket){
        this.players.set(player.id,player);
    }

    private generateRoomCode() {
        this.roomId = randomstring.generate({
            length: 6,
            charset: 'alphanumeric'
        });
    }
}

我的房间控制器类:

import {Room} from '../models/roomModel';
import {Socket} from 'socket.io';

export class RoomController {

    private rooms: Array<Room> = [];

    constructor(){

    }

    public addRoom(callingSocket:Socket){
        const newRoom = new Room(callingSocket);
        this.rooms.push(newRoom);
    }

    public getRoomCount() : number {
        return this.rooms.length;
    }
}

【问题讨论】:

    标签: socket.io jestjs


    【解决方案1】:

    问题是客户端发出事件的回调参数使用不正确。有必要在服务器套接字 .on 方法中调用回调,如下所示:

    test('should correctly display the number of rooms',(done)=>{
            expect.assertions(1);
            serverSocket.on("test_event", (callback)=>{
                roomController.addRoom(serverSocket);
                if(callback){
                    callback();
                }
            });
            clientSocket.emit('test_event');
            clientSocket.emit('test_event',(response)=>{
                done();
                expect(roomController.getRoomCount()).toEqual(2);
            });
        });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-27
      • 1970-01-01
      • 1970-01-01
      • 2020-04-01
      • 1970-01-01
      • 2018-08-05
      • 2020-02-06
      相关资源
      最近更新 更多