validation使用Mocha / Chai和asynchronous/等待引发exception

我努力想出一个最好的方法来validation在使用asynchronous/等待的同时在摩卡testing中拒绝承诺。

这是一个should.be.rejectedWith的例子,但我不喜欢should.be.rejectedWith返回一个承诺,需要从testing函数返回,以正确评估。 使用async / await可以删除testing值的这个要求(正如我对下面wins()的结果所做的那样),我觉得在某些时候我很可能会忘记return语句,在这种情况下,testing总是会通过。

 // Always succeeds function wins() { return new Promise(function(resolve, reject) { resolve('Winner'); }); } // Always fails with an error function fails() { return new Promise(function(resolve, reject) { reject('Contrived Error'); }); } it('throws an error', async () => { let r = await wins(); r.should.equal('Winner'); return fails().should.be.rejectedWith('Contrived Error'); }); 

感觉应该有可能使用async / await将exception的exception转化为exception并将其与Chai的should.throw结合起来,但是我一直无法确定正确的语法。

理想情况下,这将工作,但似乎并不:

 it('throws an error', async () => { let r = await wins(); r.should.equal('Winner'); (await fails()).should.throw(Error); }); 

这个方法的问题是(await fails()).should.throw(Error)没有意义。

await解决Promise 。 如果Promise拒绝,它抛出被拒绝的价值。

所以(await fails()).should.throw(Error)永远不能工作:如果fails()拒绝,错误抛出,并且.should.throw(Error)永远不会执行。

你所拥有的最习惯的select是使用柴的rejectedWith财产,正如你在你的问题中所表明的那样。

这是一个简单的例子。 与你在问题中所展示的不一样, 我只是使用async函数的wins()fails()expect而不是should 。 当然,你可以使用返回Promisechai.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()testing类似于你的fails()testing,你可以写下你的wins()testing:

 it('wins() returns Winner', async () => { await expect(wins()).to.eventually.equal('Winner') }) 

在这两个例子中,要记住的关键是, chai-as-promised回报承诺其职能,如rejectedWitheventually.something 。 因此,您必须在asynctestingfunction的环境中await它们,否则失败的条件仍然会通过:

 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) }) 

如果你用上面的代码运行testing,你会得到以下结果:

 $ npm test > mocha-chai-async@1.0.0 test /home/vsimonian/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) 

正如你所看到的,柴的断言实际上是失败的,但是在一个没有人await或者接受的承诺的背景下,他们失败了。 所以Mocha看不出任何失败,并将testing标记为已通过,但Node.js(在将来如上所述将改变的行为)将未处理的拒绝打印到terminal。