【问题标题】:Why does this test only fail when there is a rejection?为什么这个测试只有在被拒绝时才会失败?
【发布时间】:2021-06-29 17:05:19
【问题描述】:

此测试通过;即 sinon 说存根实际上是:

const sinon = require('sinon')

async function underTest (s){
  promise1 = new Promise((yes, no)=>yes())
  promise2 = new Promise((yes, no)=>yes())

  Promise.all([promise1, promise2]).then(s.yes).catch(s.no)
}

async function test(){
  s = {yes: sinon.stub(), no:sinon.stub()}  
  await underTest(s)
  sinon.assert.called(s.yes)
}

test().then(console.log('done'))

请注意我没有从Promise.all返回承诺。

但是,下面的测试会失败,sinon 会说存根没有被调用:

const sinon = require('sinon')

async function underTest (s){
  promise1 = new Promise((yes, no)=>no())
  promise2 = new Promise((yes, no)=>no())

  Promise.all([promise1, promise2]).then(s.yes).catch(s.no)
}

async function test(){
  s = {yes: sinon.stub(), no:sinon.stub()}  
  await underTest(s)
  sinon.assert.called(s.no)
}

test().then(console.log('done'))

如果我返回Promise.all,那么它就会通过,sinon 会说调用了s.no 存根:

const sinon = require('sinon')

async function underTest (s){
  promise1 = new Promise((yes, no)=>no())
  promise2 = new Promise((yes, no)=>no())

  return Promise.all([promise1, promise2]).then(s.yes).catch(s.no)
}

async function test(){
  s = {yes: sinon.stub(), no:sinon.stub()}  
  await underTest(s)
  sinon.assert.called(s.no)
}

test().then(console.log('done'))

只有当我从Promise.all 返回承诺时,测试才会通过。如果我什么都不返回,async 函数将解析为undefined,并且可能会或可能不会调用存根。

我的问题是,如果没有 return 语句,即使是第一种情况,我也会预料到测试会失败。我本来希望 sinon 告诉我 s.yes 没有被调用。但是为什么会通过呢?为什么resolve和reject会不一致?

【问题讨论】:

    标签: javascript node.js promise sinon


    【解决方案1】:

    我运行你的代码。不,您的第一个代码/案例测试已完成,但结果未通过。

    如果你在运行测试时也实现了 catch,你会有更好的方式来了解它:

    test()
    .then(() => console.log('done'))
    .catch((error) => console.log('Error:', error.message));
    

    您使用的异步等待不一致。

    如果您使用的是异步等待,您可以使用try and catch 捕获错误。

    例如:

    async function underTest (s){
      promise1 = new Promise((yes, no)=>yes())
      promise2 = new Promise((yes, no)=>yes())
    
      try {
        await Promise.all([promise1, promise2]);
        s.yes();
      } catch {
        s.no();
      }
      // This will return Promise<void>
    }
    

    【讨论】:

    • 感谢您抽出宝贵时间。但正如你所知道的,诗浓说,在第一种情况下,实际上称为 s.yes。而 s.no 没有被调用。应该是不使用 await 应该导致两种情况都失败,而不仅仅是一个,对吧?
    • 在您评论添加示例后,我编辑了我的答案。不,第一个案例s.yes没有被调用。我的终端中的第一种情况输出错误:错误:预期的存根至少被调用过一次但从未被调用
    • 哇,你说得对,现在它不再运行了。
    猜你喜欢
    • 2015-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多