0

I was having issues running a test (in Node),

I was simulating a promise being rejected, and my code should retry (using promise-retry if that could be relevant).

When I simulated the rejected promise using stub.returns(Promise.reject(error)

I was getting a uncaught error warnings (for my dummyErrors), even though I am catching errors where I call my function...

-note, these uncaught errors were only happening in the unit tests not in real calls.

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}));

I discovered that by changing to use the stub.rejects() syntax:

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

I no longer get the uncaught error warnings.

My issue is solved, however I would like to get a better understand as to why, I looked at the sinon source code and it looks like the implementation of .rejects is no different

4

1 に答える 1

3

キャッチされていないエラー (V8/Node.js を含む) を本質的に検出する promise 実装では、拒否された promise からのエラーは同じティックでキャッチする必要がありますUnhandledPromiseRejectionWarning

これはうまくいきます:

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

これにより、promise が処理されない可能性があり、警告がトリガーされます。

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

チェーンされていない場合、または同じティックにPromise.reject(dummyError)チェーンされていない場合、警告がトリガーされますが、拒否されたプロミスの場合、関数呼び出しで作成されるため、これはおそらく true になります。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))
于 2018-06-13T18:01:11.813 に答える