Mocha / Node:如何使用 assert.rejects()?

Mocha / Node: how to use assert.rejects()?

我尝试遵循 documentation 以使用 assert.rejects 测试错误消息(我确实有 v10 以上的节点)。

但它总是会过去,即使是一个荒谬的消息。我做错了什么?

it("should fail but it's not", 
  async ()=> {
    let itemId = 'not an id'
    assert.rejects( 
      await ListRepo.checkById(itemId),
      {message: 'abracadabra'}                        
    )
  }
)

更新: 看来如果我 return assert.rejects 就可以了。但是我还是不知道原因。

nicholaswmin 所说的是正确的,但这里有一个 "rest of the owl" 时刻我想澄清一下。

如果你的愿望是:"I want to assert reject", "I want to make sure this code rejects in the right way,"模式有点复杂。

首先,写入return fxnWhichReturnsPromise()。如果您的函数被拒绝,测试将失败,而您想要相反的结果。您必须使用 .then() 的双参数签名,它看起来像:.then(onFulfillCallback, onRejectCallback),因为如果您将它拆分为 .then.catch,则在 [=14] 中失败=]-block 将被随后的 .catch-block 捕获,应该是失败测试(它没有拒绝)将是通过测试。

实际上,它看起来像这样:

it('rejects when given foobar', () => {
  return fxnThatShouldReject(foobar)
    .then(
      (val) => { assert.fail(`Should have rejected, returned with ${val} instead`)
      ,
      (err) => { assert.equal(err.message, "Rejection reason I was expecting") }
    )
}) 

断言库没有为此内置断言处理程序的原因是因为能够 "hold-up" 在测试套件中异步执行确实是测试运行程序的能力。相比之下,assert.throws() 是同步的。

在我写这篇文章时,above/previously 写的所有内容都是正确的,但其中大部分都不必要地复杂化了。你必须 return 一个 promise 是正确的,这样 mocha 本身就有一些东西要等待,否则它会立即 return s(在你的 promise 可以解决或拒绝之前)。缺少的部分是手动等待承诺很少是您真正想要在这里做的。

@caub 在评论中暗示了这个最简单的模式——等待 return 由 assert.rejects 编辑的承诺。具体来说:

it("should fail but it's not", 
  async ()=> {
    let itemId = 'not an id'
    await assert.rejects( 
      ListRepo.checkById(itemId),
      {message: 'abracadabra'}                        
    )
  }
)

这里有三个关键点:

  1. 测试函数本身必须是async
  2. await assert.rejects 在(异步)测试函数中调用。这会自动使测试函数 return Promise<void>,这正是您想要的。这将重要部分放在 assert 调用点,与手动 returning/handling promise 相比,更容易 copy/paste 在其他地方调用,并且更容易在一次测试中断言多个拒绝。
  3. 不要 await 您传递给 rejects 调用的内容。您应该传递一个承诺——而不是 awaited 值。