这种方法的问题是(await fails()).should.throw(Error)
没有意义。
await
解决一个Promise
. 如果Promise
拒绝,则抛出拒绝的值。
所以(await fails()).should.throw(Error)
永远无法工作:如果fails()
拒绝,则会引发错误,并且.should.throw(Error)
永远不会执行。
正如您在问题中所显示的那样,您拥有的最惯用的选择是使用 Chai 的rejectedWith
属性。
这是一个简单的例子。与您在问题中展示的内容没有什么不同;我只是使用async
函数 for wins()
andfails()
而expect
不是should
. 当然,您可以使用返回 aPromise
并且chai.should
很好的函数。
const chai = require('chai')
const expect = chai.expect
chai.use(require('chai-as-promised'))
// Always succeeds
async function wins() {
return 'Winner'
}
// Always fails with an error
async function fails() {
throw new Error('Contrived Error')
}
it('wins() returns Winner', async () => {
expect(await wins()).to.equal('Winner')
})
it('fails() throws Error', async () => {
await expect(fails()).to.be.rejectedWith(Error)
})
如果您希望您的测试更接近wins()
您的fails()
测试,您可以这样编写您的wins()
测试:
it('wins() returns Winner', async () => {
await expect(wins()).to.eventually.equal('Winner')
})
在这两个示例中要记住的关键是chai-as-promised
返回对其函数的承诺,例如rejectedWith
和eventually.something
。因此,您必须await
在测试函数的上下文中使用它们async
,否则失败的条件仍然会通过:
async function wins() {
return 'Loser'
}
async function fails() {
return 'Winner'
}
it('wins() returns Winner', async () => {
expect(wins()).to.eventually.equal('Winner')
})
it('fails() throws Error', async () => {
expect(fails()).to.be.rejectedWith(Error)
})
如果您使用上面的代码运行测试,您将得到以下结果:
$ npm test
> mocha-chai-async@1.0.0 test /home/adaline/code/mocha-chai-async
> mocha .
√ wins() returns Winner
(node:13836) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rej
ection id: 1): AssertionError: expected 'Loser' to equal 'Winner'
(node:13836) [DEP0018] DeprecationWarning: Unhandled promise rejections are dep
recated. In the future, promise rejections that are not handled will terminate
the Node.js process with a non-zero exit code.
√ fails() throws Error
(node:13836) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rej
ection id: 2): AssertionError: expected promise to be rejected with 'Error' but
it was fulfilled with 'Winner'
2 passing (11ms)
如您所见,chai 断言实际上失败了,但它们在没有人await
编辑或catch
编辑的 Promise 的上下文中失败了。所以 Mocha 没有看到失败,并将测试标记为通过,但是 Node.js(在未来会发生变化的行为,如上所述)将未处理的拒绝打印到终端。