使用Cypress组件测试时SignalR WebSocket连接超时问题
解决Cypress组件测试中SignalR WebSocket连接失败问题
核心问题分析
你遇到的问题根源有两个:
- SignalR端点认知错误:SignalR的Hub通信不是普通REST API,它先通过HTTP请求
/testhub/negotiate(默认路由)完成握手协商,再升级为WebSocket连接,而非直接请求api/jobs/testhub。 cy.intercept不支持WebSocket拦截:cy.intercept只能处理HTTP/HTTPS请求,无法直接拦截WS/WSS协议的WebSocket连接,必须先Mock协商请求,或直接Stub掉SignalR的连接逻辑。
具体解决方案
方案1:Mock SignalR协商请求(避免真实连接)
先拦截SignalR的协商请求,返回模拟的握手数据,让前端认为已完成协商,不会发起真实WebSocket连接:
describe('<Jobs Page>', () => { it('verify the data displaying in jobs page', () => { cy.viewport(1000, 1000) // 1. Mock SignalR协商请求(注意端点要和后端Hub路由匹配) // 如果后端Hub路由配置了前缀(比如[Route("api/jobs/testhub")]),则URL改为/api/jobs/testhub/negotiate cy.intercept('GET', '/testhub/negotiate', { body: { connectionId: 'mock-connection-id', availableTransports: [ { transport: 'WebSockets', transferFormats: ['Text', 'Binary'] } ] } }) // 2. Mock你的REST API请求 cy.intercept("GET", "api/jobs/testhub", { fixture: 'testData.json'}) // 3. 挂载组件 cy.mount(<Job/>) }) })
方案2:Stub SignalR HubConnection(完全Mock通信)
如果需要模拟SignalR的消息推送,可以直接Stub掉HubConnectionBuilder,避免发起真实连接,同时模拟消息回调:
describe('<Jobs Page>', () => { it('verify the data displaying in jobs page', () => { cy.viewport(1000, 1000) // 1. Mock REST API cy.intercept("GET", "api/jobs/testhub", { fixture: 'testData.json'}) // 2. Stub SignalR HubConnection,模拟连接和消息 const mockJobUpdateData = { id: 1, status: 'Completed' }; // 模拟消息数据 cy.stub(window, 'HubConnectionBuilder').returns({ withUrl: () => ({ build: () => ({ start: cy.stub().resolves(), // 模拟连接成功 on: cy.stub().callsFake((eventName, callback) => { // 模拟收到SignalR推送的消息 if (eventName === 'JobStatusUpdated') { callback(mockJobUpdateData); } }) }) }) }) // 3. 挂载组件 cy.mount(<Job/>) }) })
关键注意事项
- 确认后端SignalR Hub的路由配置:如果你的Hub使用了
[Route("api/jobs/testhub")],则协商端点应为/api/jobs/testhub/negotiate,需对应修改拦截URL。 - 若使用
cypress-plugin-signalr,需确保插件配置的端点与协商URL一致,且先Mock协商请求再初始化插件。
内容的提问来源于stack exchange,提问作者Surabhi Premani
相关产品推荐
相关产品推荐

