使用sinon时出现不一致的UnhandledPromiseRejectionWarning

时间:2018-10-05 18:19:03

标签: javascript typescript promise mocha sinon

据我所知,两个对象failApiClientexplicitFailApiClient应该具有相同的类型,并且记录它们似乎同意:

console.log(failApiClient) // { getObjects: [Function: getObjects] } console.log(explicitFailApiClient) // { getObjects: [Function: getObjects] }

阅读this问题会给我正确处理此问题所需的信息,但并不能告诉我为什么生成的failApiClient会导致警告,而{{1 }} 才不是。

我已将其削减到接近重新创建情况并演示替代方法所需的最低水平:

explicitFailApiClient

import * as sinon from 'sinon'; import 'source-map-support/register'; class LocalObject { } const fakeObject = new LocalObject(); const getFakeApi = (result: Promise<LocalObject[]>) = ({getObjects: () => result}); const successObjectClient = getFakeApi(Promise.resolve([fakeObject])); // These should be equivalent, but the former causes a test error const failApiClient = getFakeApi(Promise.reject(new Error())); const explicitFailApiClient = { getObjects(): Promise<LocalObject[]> { return Promise.reject(new Error()); } }; describe('successApiClient', () => { before(() => { sinon.spy(successObjectClient, 'getObjects'); }); it('does not have a warning', async () => { // do nothing }); }); describe('failApiClient', () => { before(() => { sinon.spy(failApiClient, 'getObjects'); }); it('should not have a warning', async () => { // do nothing }); }); describe('explicitFailApiClient', () => { before(() => { sinon.spy(explicitFailApiClient, 'getObjects'); }); it('does not have a warning', async () => { // do nothing }); }); 的结果:

~/...> tsc && npm test

2 个答案:

答案 0 :(得分:1)

它们不是等效的。

在下面的代码中,当JS作为语句的参数Promise.reject时,它已经执行了,这就是为什么您得到预警UnhandledPromiseRejectionWarning的原因。

const failApiClient = getFakeApi(Promise.reject(new Error()));

相比
const explicitFailApiClient = {
  getObjects(): Promise<LocalObject[]> {
    return Promise.reject(new Error());
  }
};
调用Promise.reject时将评估其explicitFailApiClient.getObjects()

解决方案

这是我针对此问题的替代解决方案。我可以只使用Sinon的resolvesrejects

const getFakeApi = {getObjects: (result) => result};
const getFakeApiStub = sinon.stub(getFakeApi, 'getObjects');

describe('successApiClient', () => {
  before(() => {
    getFakeApiStub.resolves([fakeObject]); // success and resolves
  });

  it('does not have a warning', async () => {
    // do nothing
  });

});

describe('failApiClient', () => {
  before(() => {
    getFakeApiStub.rejects(new Error()); // make it failed
  });

  it('should not have a warning', async () => {
    // do nothing
  });
});

参考: https://sinonjs.org/releases/v6.3.5/stubs/#stubresolvesvalue

希望有帮助

答案 1 :(得分:0)

承诺可能无法解决,解决或拒绝。 “ then”用于处理分辨率,而“ catch”则用于拒绝。您抛出的拒绝没有被抓住。

尝试SomePromiseRejection().catch(err => DoSomeStuff(err))

因此,在调用explicitFailApiClient之后,有一个.catch块。