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'}
)
}
)
这里有三个关键点:
- 测试函数本身必须是
async
。
await
assert.rejects
在(异步)测试函数中调用。这会自动使测试函数 return Promise<void>
,这正是您想要的。这将重要部分放在 assert 调用点,与手动 returning/handling promise 相比,更容易 copy/paste 在其他地方调用,并且更容易在一次测试中断言多个拒绝。
- 不要
await
您传递给 rejects
调用的内容。您应该传递一个承诺——而不是 await
ed 值。
我尝试遵循 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'}
)
}
)
这里有三个关键点:
- 测试函数本身必须是
async
。 await
assert.rejects
在(异步)测试函数中调用。这会自动使测试函数 returnPromise<void>
,这正是您想要的。这将重要部分放在 assert 调用点,与手动 returning/handling promise 相比,更容易 copy/paste 在其他地方调用,并且更容易在一次测试中断言多个拒绝。- 不要
await
您传递给rejects
调用的内容。您应该传递一个承诺——而不是await
ed 值。