Sinon,使用 Promise.reject() 到 stub.rejects() 观察不同的行为
Sinon, observing different behaviour using Promise.reject() to stub.rejects()
我遇到了问题 运行 测试(在 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
的实现没有什么不同
在本质上检测未捕获错误的 promise 实现中(包括 V8/Node.js),来自被拒绝的 promise 的错误应该在同一时刻被捕获,否则它会触发 UnhandledPromiseRejectionWarning
.
这会很好用:
let promise = Promise.reject();
promise.catch(() => {});
这将导致潜在的未处理承诺并触发警告:
let promise = Promise.reject();
setTimeout(() => {
promise.catch(() => {});
});
如果 Promise.reject(dummyError)
没有与 catch(...)
或 then(..., ...)
链接在同一个报价单上,它会触发警告,而如果 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))
我遇到了问题 运行 测试(在 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
的实现没有什么不同
在本质上检测未捕获错误的 promise 实现中(包括 V8/Node.js),来自被拒绝的 promise 的错误应该在同一时刻被捕获,否则它会触发 UnhandledPromiseRejectionWarning
.
这会很好用:
let promise = Promise.reject();
promise.catch(() => {});
这将导致潜在的未处理承诺并触发警告:
let promise = Promise.reject();
setTimeout(() => {
promise.catch(() => {});
});
如果 Promise.reject(dummyError)
没有与 catch(...)
或 then(..., ...)
链接在同一个报价单上,它会触发警告,而如果 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))