【发布时间】: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;
}
}
【问题讨论】: