【问题标题】:UnhandledPromiseRejectionWarning Testing Promise RejectionUnhandledPromiseRejectionWarning 测试 Promise Rejection
【发布时间】:2018-06-14 16:43:19
【问题描述】:

我正在尝试编写一个包含.and.returnValues 承诺列表的间谍的茉莉花测试。前几个承诺是拒绝,最后一个是成功。虽然测试顺利通过,但 Node 抱怨以下内容:

UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): undefined
UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): undefined
UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 4): undefined
PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 2)
PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 3)
PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 4)

我的代码非常简单:我创建了一个间谍,将其注入我的代码中,调用我的代码,该代码将循环调用我的间谍直到它不拒绝,然后监视它被调用了 5 次。间谍是这样的:

var spy = jasmine.createSpy("spy").and.returnValues(
    Promise.reject(),
    Promise.reject(),
    Promise.reject(),
    Promise.reject(),
    Promise.resolve(true)
);

// Inject the spy...

// This will resolve only when the Promise-returning function it calls resolves without rejecting.
myFunc()   
    .then(() => {
        expect(spy).toHaveBeenCalledTimes(5);
        done();
    })
    .catch();

被测代码在它的链中最后是一个空的.catch(),以验证我没有在那里引起问题。 AFICT,问题是 Node 看到我在做 Promise.reject() 并认为这是未处理的,而实际上它已被处理。

如何正确测试被拒绝的 Promise?我觉得 Jasmine 需要 this 之类的东西。

【问题讨论】:

  • 你为什么不使用async await,将await 包裹在try..catch..finally 块中,然后你可以在finally 块中使用expect(spy).toHaveBeenCaledTimes(5)
  • 我在节点 6 上,不支持 async/await

标签: javascript node.js promise jasmine jasmine-node


【解决方案1】:

这是因为您稍后在事件队列中的某处捕获被拒绝的 Promise,而不是在创建 Promise 的同一调用堆栈中。

解决办法是:

var unsafeReject = p => {
  p.catch(ignore=>ignore);
  return p;
};

var p = Promise.reject("will cause warning");

//will catch reject on queue, not on stack
setTimeout(
  ()=>p.catch(e=>console.log("reject:",e))
);

var q = unsafeReject(Promise.reject("will NOT cause warning"));
setTimeout(
  ()=>q.catch(e=>console.log("reject:",e))
);

【讨论】:

  • 你的意思是safeReject
  • @Bergi 正确,实际上名称是错误的,应该是 unsafeReject 因为传入的承诺在被拒绝时不会在控制台中“爆炸”,但仍然可以在返回的承诺中被捕获。我将其重命名为unsafeReject
  • 我想我会使用handled(Promise.reject(…))handledRejection(…)。我不会使用“安全”的术语,因为它是安全的拒绝(没有炸毁任何东西)还是安全的,因为你不能错过拒绝。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 2021-07-09
  • 2018-01-11
  • 1970-01-01
相关资源
最近更新 更多