【问题标题】:Sinon, observing different behaviour using Promise.reject() to stub.rejects()Sinon,使用 Promise.reject() 到 stub.rejects() 观察不同的行为
【发布时间】:2018-06-13 17:43:22
【问题描述】:

我在运行测试时遇到了问题(在 Node 中),

我正在模拟一个被拒绝的承诺,我的代码应该重试(如果可能相关,请使用 promise-retry)。

当我使用stub.returns(Promise.reject(error)模拟被拒绝的承诺时

我收到了一个未捕获的错误警告(对于我的dummyErrors),即使我在调用我的函数时发现了错误...

-注意,这些未捕获的错误只发生在单元测试中,而不是实际调用中。

const mockedFunction = sinon.stub();

const dummyError = new Error('Document is locked');

mockedFunction.onCall(0).returns(Promise.reject(dummyError));
mockedFunction.onCall(0).returns(Promise.reject(dummyError));
mockedFunction.onCall(0).returns(Promise.reject(dummyError));
mockedFunction.onCall(1).returns(Promise.resolve({approved: true}));

我发现通过更改为使用stub.rejects() 语法:

mockedFunction.onCall(0).rejects(dummyError);
mockedFunction.onCall(1).rejects(dummyError);
mockedFunction.onCall(2).rejects(dummyError));
mockedFunction.onCall(3).resolves({approved: true});

我不再收到未捕获的错误警告。

我的问题解决了,但是我想更好地理解为什么,我查看了 sinon 源代码,看起来.rejects 的实现没有什么不同

【问题讨论】:

    标签: javascript node.js promise sinon chai-as-promised


    【解决方案1】:

    在本质上检测未捕获错误的 Promise 实现中(包括 V8/Node.js),来自被拒绝的 Promise 的错误应该在同一滴答声中被捕获,否则会触发 UnhandledPromiseRejectionWarning

    这样可以正常工作:

    let promise = Promise.reject();
    promise.catch(() => {});
    

    这将导致潜在的未处理承诺并触发警告:

    let promise = Promise.reject();
    setTimeout(() => {
      promise.catch(() => {});
    });
    

    如果Promise.reject(dummyError) 没有与catch(...)then(..., ...) 在同一个tick 上链接,它会触发警告,而在rejects(dummyError) 的情况下,函数调用会创建一个被拒绝的承诺,所以这很可能是真的:

    sinon.spy(Promise, 'reject');
    mockedFunction.onCall(0).rejects(dummyError);
    expect(Promise.reject).to.have.not.been.called;
    mockedFunction();
    expect(Promise.reject).to.have.been.called;
    

    rejects(dummyError) 的替代方案是:

    mockedFunction.onCall(0).callsFake(() => Promise.reject(dummyError))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-23
      • 2017-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-10
      • 2019-10-09
      相关资源
      最近更新 更多