You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Mocha等待SSE协议Web服务返回数据后再完成测试(基于Mocha+Chai+Node.js+Express)

How to Make Mocha Wait for SSE (EventSource) Messages Before Passing Tests

The issue you're seeing is because Mocha treats your test case as synchronous by default. Your test function finishes executing right after creating the EventSource instance, so Mocha marks it as passed immediately—before the onmessage callback ever runs. That's why even your obviously failing assertion (expect(false).to.equal(true)) doesn't affect the test result.

To fix this, you need to tell Mocha to wait for the asynchronous SSE message to arrive. There are two standard ways to handle async tests in Mocha: using the done callback, or returning a Promise.

Solution 1: Use the done Callback

Add the done parameter to your test function. Mocha will wait until you call done() (to signal success) or done(error) (to signal failure) before marking the test as complete.

import { expect } from 'chai';
var EventSource = require('eventsource');

describe('Connection tests', () => {
  it('checks for connection', (done) => {
    // Extend timeout if needed (Mocha defaults to 2000ms)
    this.timeout(5000);

    const source = new EventSource('http://localhost:3000/api/v1/prenotazione?subscribe=300');

    // Handle incoming messages
    source.onmessage = (e: any) => {
      try {
        // Replace this with your actual assertion
        expect(e.data).to.be.a('string').and.not.be.empty;
        
        // Clean up the connection and signal test success
        source.close();
        done();
      } catch (err) {
        // If assertion fails, close connection and pass error to Mocha
        source.close();
        done(err);
      }
    };

    // Handle connection errors to avoid hanging tests
    source.onerror = (err: any) => {
      source.close();
      done(new Error(`SSE connection failed: ${err}`));
    };
  });
});

Solution 2: Return a Promise

Wrap your EventSource logic in a Promise. Mocha will automatically wait for the Promise to resolve (success) or reject (failure).

import { expect } from 'chai';
var EventSource = require('eventsource');

describe('Connection tests', () => {
  it('checks for connection', () => {
    return new Promise((resolve, reject) => {
      const source = new EventSource('http://localhost:3000/api/v1/prenotazione?subscribe=300');

      source.onmessage = (e: any) => {
        try {
          // Your actual assertion here
          expect(e.data).to.contain('expected-content');
          
          source.close();
          resolve();
        } catch (err) {
          source.close();
          reject(err);
        }
      };

      source.onerror = (err: any) => {
        source.close();
        reject(new Error(`SSE connection error: ${err}`));
      };

      // Optional: Add a timeout to prevent infinite hanging
      setTimeout(() => {
        source.close();
        reject(new Error('Test timed out waiting for SSE message'));
      }, 5000);
    });
  });
});

Key Notes

  • Always clean up: Call source.close() after handling the message or error to avoid leaving open connections.
  • Handle timeouts: If your SSE endpoint might take longer than Mocha's default 2-second timeout, use this.timeout(ms) (with the done approach) or a setTimeout (with the Promise approach) to prevent false failures.
  • Catch assertion errors: When using done, wrap your assertions in a try/catch block—otherwise, a failed assertion will throw an error that Mocha won't catch, and the test will hang indefinitely.

内容的提问来源于stack exchange,提问作者Lucio Crusca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 22:12:28