将 Cypress 与“模拟套接字”一起使用

Jon*_*man 5 mocking websocket cypress

我正在尝试与 Cypress 一起使用,在我的块中mock-sockets设置钩子中的onBeforeLoad模拟。我可以让一个测试正常工作,但是当模拟设置在下一个测试上运行时cy.visit()beforeEachbeforeEach我收到一个错误A mock server is already listening on this url

\n\n

测试中的代码:

\n\n

(从我的 React 应用程序调用componentDidiMount

\n\n
  subscribeToSettings(url: string): W3CWebSocket {\n    let settingsSubscription = new W3CWebSocket(url);\n    settingsSubscription.onopen = () => console.log(\'WebSocket Client Connected (settings)\');\n    settingsSubscription.onclose = () => console.log(\'WebSocket Client Disconnected (settings)\');\n    settingsSubscription.onmessage = (message: MessageEvent) => this.handleSettingsMessage(message);\n    return settingsSubscription;\n  }\n\n  /**\n   * Handler for websocket settings messages, which updates the local settings values.\n   * @param message the websocket message\n   */\n  handleSettingsMessage(message: MessageEvent) {\n    const updatedValues = JSON.parse(message.data);\n    console.log(\'A message was received on the settings channel.\', updatedValues);\n    this.props.updateSettingsFromBackend(updatedValues);\n  }\n
Run Code Online (Sandbox Code Playgroud)\n\n

柏树测试

\n\n
import { Server } from \'mock-socket\'\nimport { defaultSettingsState } from "../../src/reducers/settings.reducer";\nimport { _createSettingsApiPutPayload } from "../../src/actions/settings.actions";\n\ndescribe(\'mock socket method 1\', () => {\n  let mockSocket;\n  let mockServer;\n  beforeEach(() => {\n    cy.visit(\'/\', {\n      onBeforeLoad(win: Window): void {\n        // @ts-ignore\n        cy.stub(win, \'WebSocket\', url => {\n          mockServer = new Server(url)\n          mockServer.on(\'connection\', socket => {\n            console.log(\'mock socket connected\');\n            mockSocket = socket;\n          });\n          mockSocket = new WebSocket(url);\n          return mockSocket\n        });\n      },\n    });\n  });\n\n  afterEach(() => {\n    mockSocket.close()\n    mockServer.stop()\n  });\n\n  it(\'gets a message\', () => {\n    cy.contains(\'SETTINGS\').click()\n    const object = _createSettingsApiPutPayload(defaultSettingsState)\n    mockSocket.send(JSON.stringify(object));\n    cy.contains(\'Motion threshold\')\n  });\n  it(\'gets another message\', () => {\n    cy.contains(\'SETTINGS\').click()\n    const object = _createSettingsApiPutPayload(defaultSettingsState)\n    mockSocket.send(JSON.stringify(object));\n    cy.contains(\'Motion threshold\')\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

以下是我的控制台的日志:

\n\n
WebSocket Client Connected (settings)\nmock socket connected at url ws://localhost:8702/PM_Settings\nA message was received on the settings channel. {\xe2\x80\xa6}\nmock socket connected at url ws://localhost:3000/sockjs-node/949/mhuyekl3/websocket\nThe development server has disconnected.\nRefresh the page if necessary.\nUncaught Error: A mock server is already listening on this url\n
Run Code Online (Sandbox Code Playgroud)\n\n

我想知道这是否与第二个调用有关某些神秘网址有关。

\n\n

(注意:即使在第一个测试中,cy.contains(\'SETTINGS\').click()在某种程度上结束调用也beforeEach不起作用。即使我将应用程序设置为在设置页面上启动(而不是必须从测试内部单击它),单击SETTINGSbeforeEach仍然不起作用。所以这有点奇怪)

\n\n

这些 cypress 日志也可能有帮助:\n在此输入图像描述

\n

Tit*_*nis 2

WebSocket当我将服务器停止移动到存根时,它只对我有用:

cy.stub(window, 'WebSocket', url => {
  if (mockServer) {
    mockServer.stop();
  }
  mockServer = new Server(url);
  mockServer.on('connection', socket => {
    mockSocket = socket;
  });
  mockSocket = new WebSocket(url);
  return mockSocket;
});
Run Code Online (Sandbox Code Playgroud)

我可能错了,但我猜afterEach或者mockServer.stop();是异步的,这就是为什么模拟服务器无法在新的初始化之前停止的原因