在Jest中模拟WebSocket

17

我正在尝试测试一个使用WebSockets的库。 我正试图使用以下代码模拟websocket。库ROSController使用websockets,但我不断收到WebSocket未定义的错误。

import { ROSController }  from '../ROSController.jsx';
var socketMock;
var windowMock;
var address = 'ws://test.address';

beforeAll(function() {
    var WebSocket = jasmine.createSpy();
    WebSocket.and.callFake(function (url) {
      socketMock = {
        url: url,
        readyState: WebSocket.CONNECTING,
        send: jasmine.createSpy(),
        close: jasmine.createSpy().and.callFake(function () {
          socketMock.readyState = WebSocket.CLOSING;
        }),

        // methods to mock the internal behaviour of the real WebSocket
        _open: function () {
          socketMock.readyState = WebSocket.OPEN;
          socketMock.onopen && socketMock.onopen();
        },
        _message: function (msg) {
          socketMock.onmessage && socketMock.onmessage({data: msg});
        },
        _error: function () {
          socketMock.readyState = WebSocket.CLOSED;
          socketMock.onerror && socketMock.onerror();
        },
        _close: function () {
          socketMock.readyState = WebSocket.CLOSED;
          socketMock.onclose && socketMock.onclose();
        }
      };
      return socketMock;
    });
    WebSocket.CONNECTING = 0;
    WebSocket.OPEN = 1;
    WebSocket.CLOSING = 2;
    WebSocket.CLOSED = 3;
    windowMock = {
      WebSocket: WebSocket
    };

    return WebSocket;
});

test('the subscription JSON produced is correct', () => {
    console.log(WebSocket); //<----- It fails here
    JSON.parse((new ROSController('')).callService('/test','', function(){}));

});

jasmine 声明在哪里? - jered
在我的 package.json 文件中,我只是在项目的根目录下运行 Jest。这个命令在 scripts/tests 文件夹中执行。Jest 似乎可以正常运行,但我无法获取 WebSocket 变量。 - cjds
3个回答

16
使用mock-socket包和global,使其在nodejs下可用:
import { WebSocket } from 'mock-socket';

global.WebSocket = WebSocket;

7
我以前用过 mock-socket,但我建议大家避免使用它。它并没有得到很好的维护,而且存在各种各样的漏洞(其中许多已经存在多年)。虽然我还没有找到比编写自己的模拟实现更好的替代方案,但每次我不得不这样做时,花费的时间都比在 mock-socket 中解决问题要少。 - Mattia
mock-socket很受欢迎:每周下载量达到50万次。对我来说也运行良好。或许Mattia的评论已经不再相关了? - Ben Butterworth

10

开玩笑的时候,你需要将应该在全局作用域中可用的东西(即window)添加到global命名空间中:

global.WebSocket= WebSocket

这对我不起作用。我已经在测试设置和单元测试中将WebSocket添加到全局范围中。在两种情况下,我都会收到“ReferenceError:WebSocket未定义”的错误。 - Daniel Reina

0
我创建了一个文件 __mocks__/ws.js:
const {WebSocket} = require("mock-socket");

module.exports = WebSocket

请查看jest-websocket-mock的说明:

// mocks/ws.js

export { WebSocket as default } from "mock-socket";

以及手动模拟文档

模拟应该放置在__mocks__目录中...并将被自动模拟。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接