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

使用Mocha、Sinon、Chai测试时,Promise未解析致断言失败问题

解决Mocha中Promise未等待导致Spy断言失败的问题

我完全懂你碰到的这个坑——你的测试代码没等fn.method()返回的Promise解析就跑去执行断言了,所以expect(test).to.have.been.called会在then回调触发前就跑完,自然断言失败,打印顺序也乱了套。

问题根源

Mocha默认不会自动等待异步操作(比如Promise)完成。你原来的代码里,fn.method().then(...)是异步执行的,但测试函数会同步走完所有代码:先调用fn.method(),然后立刻执行console.log("goodbye")和expect(test)...,这时候then里的test()还没机会执行,spy自然没被调用。

解决方案:让Mocha等待Promise完成

有两种常用的方式可以解决这个问题,都能保证断言在then回调执行后才运行,同时让打印顺序符合你的预期。

1. 返回Promise给Mocha

Mocha会自动识别测试函数返回的Promise,并等待它resolve后再结束测试。把你的断言放到Promise链的后续then里,就能确保顺序正确:

const sinon = require('sinon');
const { expect } = require('chai');

describe('异步方法测试', () => {
  it('应正确调用test spy并按预期顺序打印', () => {
    let test = sinon.spy();
    let fn = { method: sinon.stub().resolves("hello") };

    // 返回Promise链,让Mocha等待所有异步操作完成
    return fn.method().then(response => {
      console.log(response); // 先打印"hello"
      test();
    }).then(() => {
      console.log("goodbye"); // 再打印"goodbye"
      // 现在断言才会在test被调用后执行
      expect(fn.method).to.have.been.called;
      expect(test).to.have.been.called;
    });
  });
});

2. 使用async/await(更简洁的写法)

现代JS里用async/await处理异步会更直观,Mocha完全支持async测试函数,它会自动等待await后的Promise完成:

const sinon = require('sinon');
const { expect } = require('chai');

describe('异步方法测试', () => {
  it('应正确调用test spy并按预期顺序打印', async () => {
    let test = sinon.spy();
    let fn = { method: sinon.stub().resolves("hello") };

    // 等待Promise解析
    const response = await fn.method();
    console.log(response); // 先打印"hello"
    test();

    console.log("goodbye"); // 再打印"goodbye"
    // 此时test已经被调用,断言会通过
    expect(fn.method).to.have.been.called;
    expect(test).to.have.been.called;
  });
});

效果验证

修改后,测试会先等待fn.method()的Promise resolve,执行then回调里的console.log("hello")和test(),之后再打印"goodbye"并执行断言,完全符合你的预期,expect(test).to.have.been.called也会顺利通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:21:07