我想用Jest對這個JS代碼進行單元測驗。它使用 ws websocket 庫:
套接字.js
import WebSocket from "ws";
export default class Socket {
socket = undefined;
connect(url): void {
if (this.socket !== undefined && this.socket.readyState === WebSocket.OPEN) {
throw new Error("Socket is already connected");
}
this.socket = new WebSocket(url);
}
}
我想檢查錯誤是否被拋出。為此,我為套接字創建了一個模擬,然后需要將readyState套接字物件的CLOSED. 問題是這是不可能的,因為它是一個只讀欄位。
測驗:
import Socket from "./Socket";
import WebSocket from "ws";
jest.mock("ws");
it("can connect", () => {
// Arrange
const url = "www.someurl.com";
jest.spyOn(global, "Promise").mockReturnValueOnce({} as Promise<void>);
const sut = new Socket();
// Act
sut.connect(url);
const webSocket = jest.mocked(WebSocket).mock.instances[0];
// Set readystate of socket
webSocket.readyState = WebSocket.CLOSED; // Error here: Cannot assign to 'readyState' because it is a read-only property. ts(2540)
const action = () => sut.connect(url);
// Assert
expect(action).toThrowError(new Error("Socket is already connected"));
});
問題:如何測驗在模擬庫上使用只讀欄位的任何代碼,例如socket.readyState?
編輯:根據上面的請求添加了 mvce。
uj5u.com熱心網友回復:
更好的測驗策略是創建一個測驗 WebSocket 服務器并連接它。這也是官方團隊做的,看一些測驗用例。ws不建議模擬和測驗實作細節。
下面使用 TypeScript 測驗代碼:
socket.ts:
import WebSocket from "ws";
export default class Socket {
socket!: WebSocket;
connect(url: string): void {
if (this.socket !== undefined && this.socket.readyState === WebSocket.OPEN) {
throw new Error("Socket is already connected");
}
this.socket = new WebSocket(url);
}
}
socket.test.ts:
import WebSocket from "ws";
import Socket from "./socket";
describe('74062437', () => {
test('should connect the websocket server', (done) => {
const wss = new WebSocket.Server({ port: 0 }, () => {
const socket = new Socket()
socket.connect(`ws://localhost:${(wss.address() as WebSocket.AddressInfo).port}`);
socket.socket.on('open', () => {
expect(socket.socket.readyState).toEqual(WebSocket.OPEN);
socket.socket.close();
});
socket.socket.on('close', () => wss.close(done));
});
});
test('should throw error if already connected websocket server', (done) => {
expect.assertions(2);
const wss = new WebSocket.Server({ port: 0 }, () => {
const socket = new Socket();
socket.connect(`ws://localhost:${(wss.address() as WebSocket.AddressInfo).port}`);
socket.socket.on('open', () => {
expect(socket.socket.readyState).toEqual(WebSocket.OPEN);
expect(() => socket.connect(`ws://localhost:${(wss.address() as WebSocket.AddressInfo).port}`)).toThrowError('Socket is already connected')
socket.socket.close();
});
socket.socket.on('close', () => wss.close(done));
});
});
});
測驗結果:
PASS stackoverflow/74062437/socket.test.ts (10.964 s)
74062437
? should connect the websocket server (31 ms)
? should throw error if already connected websocket server (6 ms)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
socket.ts | 100 | 100 | 100 | 100 |
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 11.784 s
包版本:
"ws": "^8.9.0",
"jest": "^26.6.3"
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/515015.html
上一篇:為什么有時第二個測驗在使用AngularJasmine單元測驗的第一個測驗之后執行?
下一篇:在非可選輸入引數上測驗None
