使用chai-as-promised时Promise拒绝未触发测试失败仅输出警告
我完全懂你遇到的糟心情况——明明readIndex的Promise因为"file not found"被拒绝了,但测试没像预期那样抛出AssertionError失败,反而只弹出个未处理Promise拒绝的警告。这核心问题是你没正确处理chai-as-promised的异步断言逻辑,导致测试提前结束,根本没等到断言执行完成。
问题根源
chai-as-promised的断言(比如should.be.fulfilled)本身是返回Promise的异步操作,但你的测试代码里直接调用了done(),完全没等断言跑完就结束了测试流程。同时,原Promise的拒绝状态没有被任何代码捕获,所以Node.js抛出了未处理拒绝的警告,但测试进程已经提前结束,没机会触发断言失败。
两种正确的解决方式
方式1:返回断言的Promise(推荐)
Mocha支持测试函数返回Promise,它会自动等待这个Promise完成,不需要手动调用done()。修改你的测试代码如下:
chai.use(chaiAsPromised) chai.should() describe('SUCCESS :', () => { it('should resolve with a (markdown) string extrapoled from target folder index file', () => { const key = 'content success' mock(_mocks[key]) const promise = readIndex('test') // 返回断言的Promise,让Mocha等待它完成 return promise.should.be.fulfilled }) })
方式2:使用notify(done)
如果你习惯用done()回调,可以在断言后调用.notify(done),明确告诉Mocha什么时候断言执行完成:
chai.use(chaiAsPromised) chai.should() describe('SUCCESS :', () => { it('should resolve with a (markdown) string extrapoled from target folder index file', done => { const key = 'content success' mock(_mocks[key]) const promise = readIndex('test') // 用notify通知Mocha断言完成时调用done promise.should.be.fulfilled.notify(done) mock.restore() }) })
为什么should.not.be.rejected也有同样问题?
逻辑是一样的——这个断言同样是异步的,你没等待它完成就结束了测试,所以哪怕逻辑矛盾,测试也会通过,同时原Promise的拒绝没被捕获,警告依然存在。用上面两种方式修改后,这个断言也会正确触发失败。
额外说明
当你正确使用chai-as-promised的异步断言后,原Promise的拒绝状态会被断言捕获,不会再出现未处理Promise拒绝的警告,同时断言会正确判断Promise的状态,触发预期的AssertionError让测试失败。
内容的提问来源于stack exchange,提问作者imrok

