介绍
在不断发展的实时应用程序世界中,WebSocket Communication已成为一种强大的工具,可以在客户和服务器之间建立无缝有效的连接。 Nestjs是一种流行的打字稿框架,已将Websocket Gateways合并,以简化其生态系统中的实时通信。尽管使用Nestjs实施WebSocket功能无疑令人兴奋,但确保其可靠,有效地起作用至关重要。这就是测试起关键作用的地方。
欢迎获得有关为Nestjs Websocket网关创建测试的综合指南。在本文中,我们将研究Websocket Gateways的基础知识,并演示如何制定强大而有效的测试以验证其行为。
您是想扩大知识的经验丰富的Nestjs开发人员还是热衷于探索Websocket网关的新移民,本文将为您提供有价值的见解和实用示例,以开始掌握在Nestjs中测试实时功能的艺术应用。
第1部分:设置您的Nestjs Websocket网关:逐步指南
在我们指南的第一部分中,我们将带您完成设置具有WebSocket功能并生成聊天网关的Nestjs应用程序的过程。在本节结束时,您将有一个坚实的基础,可以开始构建基于WebSocket的应用程序并为其编写测试。
步骤1:安装Nestjs CLI
要开始,请确保您在计算机上安装了node.js。
如果您尚未安装Nestjs命令行界面(CLI),则可以通过运行以下命令在全球上进行:
npm i -g @nestjs/cli
步骤2:创建一个新的NEST应用程序
安装了Nestjs CLI后,通过执行以下命令来创建一个新的Nest应用程序:
nest new nest-app
在设置过程中,您将提示您选择一个软件包管理器。对于本教程,我们将使用NPM,因此请在提示时继续选择它。
生成应用程序后,使用以下命令导航到项目目录:
cd nest-app
步骤3:安装所需软件包
为了将Websocket功能添加到我们的应用程序中,我们需要安装必要的软件包。运行以下命令以安装 @nestjs/websockets和 @nestjs/platform-socket.io:
npm i --save @nestjs/websockets @nestjs/platform-socket.io
步骤4:生成聊天网关
安装了所需的软件包,让我们创建聊天网关。网关将处理Websocket连接并促进实时通信。使用Nest CLI生成聊天网关样板代码:
nest generate gateway chat
此命令将创建名为chat.gateway.ts and Chat.gateway.spec.ts的新文件,您可以使用您选择的文本编辑器打开它:
vim src/chat/chat.gateway.ts
在打开聊天网关文件时,您将找到网关的基本结构,包括带有WebSocketGateway装饰器的类定义。我们将基于此结构并随着文章的发展而添加更多功能。
恭喜!此时,您已经成功地设置了具有WebSocket功能的Nestjs应用程序,并生成了聊天网关。在下一节中,我们将深入研究Websocket网关并开始编写测试以确保其适当的功能。
第2部分:实施聊天网关并了解代码
在本节中,我们将用更丰富的Chatgateway实现替换样板代码。我们将探索代码的每个部分,了解其目的,并讨论我们所做的更改。
在我们研究代码之前,让我们简要介绍网关中使用的每个接口和装饰器的目的:
-
@WebSocketGateway()
:此装饰器将同类标记为Websocket网关,允许其处理Websocket连接和事件。 -
@WebSocketServer()
:此装饰器将Websocket Server实例(socket.io实例)注入网关,启用与已连接的客户的直接通信。 -
OnGatewayInit
:此接口提供了一个方法afterInit()
,该方法在初始化WebSocket网关时将执行。这是执行与网关初始化有关的任何设置或记录的好地方。 -
OnGatewayConnection
:此接口提供了一个方法handleConnection(client: any, ...args: any[])
,该方法在建立新的WebSocket连接时被调用。在这里,您可以处理与客户连接有关的任务,例如记录或广播欢迎消息。 -
OnGatewayDisconnect
:此接口提供了一个方法handleDisconnect(client: any)
,该方法在websocket client断开连接时会触发。您可以使用此方法执行任何清理任务或记录断开事件。 -
@SubscribeMessage('ping')
:此装饰器指出,handleMessage(client: any, data: any)
方法将使用从客户端发送的事件名称“ ping”处理消息。在我们的情况下,它只是记录了收到的消息并返回一个名为“ Pong”的响应事件,并带有固定的响应数据。
现在,让我们仔细看看我们对Chatgateway所做的代码更改:
import { Logger } from "@nestjs/common";
import {
OnGatewayConnection,
OnGatewayDisconnect,
OnGatewayInit,
SubscribeMessage,
WebSocketGateway,
WebSocketServer,
} from "@nestjs/websockets";
import { Server } from "socket.io";
@WebSocketGateway()
export class ChatGateway
implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{
private readonly logger = new Logger(ChatGateway.name);
@WebSocketServer() io: Server;
afterInit() {
this.logger.log("Initialized");
}
handleConnection(client: any, ...args: any[]) {
const { sockets } = this.io.sockets;
this.logger.log(`Client id: ${client.id} connected`);
this.logger.debug(`Number of connected clients: ${sockets.size}`);
}
handleDisconnect(client: any) {
this.logger.log(`Cliend id:${client.id} disconnected`);
}
@SubscribeMessage("ping")
handleMessage(client: any, data: any) {
this.logger.log(`Message received from client id: ${client.id}`);
this.logger.debug(`Payload: ${data}`);
return {
event: "pong",
data: "Wrong data that will make the test fail",
};
}
}
在上面的代码中,我们用更有功能的实现替换了先前的样板网关:
-
我们从
@nestjs/common
和@nestjs/websockets
导入了所需的模块和类,以及'socket.io'的Server
class。 -
我们使用
@nestjs/common
定义了一个记录器,以方便网关内的记录。该记录仪在测试过程中将很有帮助。 -
在
afterInit()
方法中,我们记录了一条简单的消息,指示Websocket网关已初始化。这对于跟踪应用程序的生命周期可能很有用。 -
在
handleConnection(client: any, ...args: any[])
方法中,我们处理了一个新的WebSocket连接。我们记录了客户端的ID和连接客户端的总数,以跟踪活动连接。 -
handleDisconnect(client: any)
方法负责记录断开事件。当Websocket客户端断开连接时,将调用此方法执行任何必要的清理或记录。 -
我们实现了一个名为
handleMessage(client: any, data: any)
的@SubscribeMessage('ping')
方法。此方法处理连接客户端的事件名称“ ping”的传入消息。它将收到的消息与其有效载荷一起记录,并返回一个名为“ Pong”的固定响应事件,其中包含有意错误的消息的数据字段。我们添加了这个故意的错误,以说明如何在即将到来的部分中测试错误行为。
使用新的ChatGateway,我们的WebSocket应用程序现在可以处理客户的连接,断开连接和传入的消息。在本文的下一部分中,我们将重点介绍该网关的编写测试,以确保其适当的功能和鲁棒性。
第3部分:Nestjs Websocket网关编写测试
在指南的最后一部分中,我们将探讨如何为我们之前创建的Chatgateway编写测试。在本节结束时,您将进行一套测试,以确保您的Websocket网关可靠地和预期。
让我们打开测试文件:
vim src/chat/chat.gateway.spec.ts
并将样板代码替换为以下测试:
import { Test } from "@nestjs/testing";
import { ChatGateway } from "./chat.gateway";
import { INestApplication } from "@nestjs/common";
import { Socket, io } from "socket.io-client";
async function createNestApp(...gateways: any): Promise<INestApplication> {
const testingModule = await Test.createTestingModule({
providers: gateways,
}).compile();
return testingModule.createNestApplication();
}
describe("ChatGateway", () => {
let gateway: ChatGateway;
let app: INestApplication;
let ioClient: Socket;
beforeAll(async () => {
// Instantiate the app
app = await createNestApp(ChatGateway);
// Get the gateway instance from the app instance
gateway = app.get<ChatGateway>(ChatGateway);
// Create a new client that will interact with the gateway
ioClient = io("http://localhost:3000", {
autoConnect: false,
transports: ["websocket", "polling"],
});
app.listen(3000);
});
afterAll(async () => {
await app.close();
});
it("should be defined", () => {
expect(gateway).toBeDefined();
});
it('should emit "pong" on "ping"', async () => {
ioClient.connect();
ioClient.emit("ping", "Hello world!");
await new Promise<void>((resolve) => {
ioClient.on("connect", () => {
console.log("connected");
});
ioClient.on("pong", (data) => {
expect(data).toBe("Hello world!");
resolve();
});
});
ioClient.disconnect();
});
});
在此测试文件中,我们使用@nestjs/testing
软件包来设置测试模块并编译以创建Nestjs应用程序实例。 createNestApp()
功能将ChatGateway作为参数,并返回初始化的应用程序。
然后,我们创建一个socket.io client(ioClient
),该客户端连接到http://localhost:3000
的Websocket服务器。 autoConnect: false
选项可确保客户端不会自动连接,我们将传输指定为“ Websocket”和“轮询”,以便Websocket连接是默认的尝试连接选项。
现在,让我们浏览我们写过的两个测试:
-
第一个测试只需检查Chatgateway是否定义。我们希望该网关在实例化后定义。这确保了网关设置正确并准备好处理WebSocket连接。
-
第二个测试模拟了从客户端到服务器的“ ping”事件。我们希望服务器以“ pong”事件做出响应,其中包含与“ ping”事件中发送的相同数据的响应。但是,当前的
handleMessage()
实现在响应中返回错误的数据,这导致测试失败。
要运行测试,首先安装socket.io-client软件包:
npm install -D socket.io-client
注意:您不需要安装 @types/socket.io-client类型,因为它已经在主软件包中。
并在另一个外壳窗口中使用以下命令:
npm run test:watch
在观察模式下运行的测试套件,对Chatgateway或测试文件进行的任何更改都会触发测试自动重新运行,以确保您的Websocket网关在整个开发过程中保持强大并进行了适当的测试。
一个测试未预期。
要在网关的handleMessage()
方法中修复错误,请如下更新:
@SubscribeMessage("ping")
handleMessage(client: any, data: any) {
this.logger.log(`Message received from client id: ${client.id}`);
this.logger.debug(`Payload: ${data}`);
return {
event: "pong",
data,
};
}
现在,通过正确实施,测试应成功通过。
恭喜!您已经成功设置并测试了Nestjs Websocket网关。凭借有关如何测试WebSocket功能的知识,您可以自信地使用Nestjs开发实时应用程序,因为您知道您的WebSocket通信是可靠且高效的。
感谢您加入我的旅程,与Nestjs一起探索WebSocket网关!我希望您对您的实时申请开发努力发现本指南的信息和有价值。
如果您喜欢阅读本文并发现它有帮助,请考虑对其进行大拇指或在下面发表评论。您的反馈和参与鼓励我创建更多这样的内容,帮助社区一起学习和成长。
愉快的编码,并希望您的Websoket-Power应用程序随着Nestjs的身份蓬勃发展! ðð