单元测试中Promise无法resolve的问题排查
解决单元测试中Promise无法Resolve导致超时的问题
看起来你遇到的核心问题是Promise中的断言错误没有被Mocha正确捕获,进而导致测试超时。我来帮你拆解问题并给出具体解决方案:
问题1:带done的测试用例超时原因
你的第一个测试用例里,expect(true).to.be.false会抛出断言错误,但这个错误是在Promise.then回调里抛出的——Promise会自动捕获内部抛出的错误,不会将其抛到全局环境,这就导致done()永远不会被执行,Mocha一直等到超时。
修复方案
给Promise添加catch回调,把错误传递给done:
it('should break', function(done){ const promise = Promise.resolve([1, 2, 3, 4 , 5]); promise.then(function(){ expect(true).to.be.false; done(); }).catch(done); // 将Promise的错误传递给Mocha的done方法 });
或者更简洁的async/await写法(如果你的环境支持ES2017):
it('should break', async function(){ await Promise.resolve([1, 2, 3, 4 , 5]); expect(true).to.be.false; });
这种写法下,断言错误会直接转化为Promise的rejection,Mocha能自动识别并标记测试失败。
问题2:返回Promise的用例在实际项目失效的原因
这个用例在示例项目能跑但实际项目不行,大概率是环境配置差异导致的,你可以从这几个方向排查:
1. Promise Polyfill缺失
如果你的实际项目TypeScript target设为ES5,原生环境没有Promise,需要手动引入polyfill:
- 在
tsconfig.json的lib数组中添加ES2015.Promise:{ "compilerOptions": { "lib": ["ES5", "ES2015.Promise", "DOM"] } } - 或者在Webpack entry中加入
core-js/es6/promise或babel-polyfill,确保Promise能正常工作。
2. 全局Promise错误被拦截
检查项目中是否有全局的unhandledrejection事件监听,比如:
window.addEventListener('unhandledrejection', (event) => { event.preventDefault(); // 处理错误的逻辑 });
这种监听会吃掉Promise的rejection,导致Mocha无法检测到测试失败,进而超时。
3. Webpack/Karma配置问题
确认Karma的Webpack配置是否正确处理了TypeScript编译后的代码,比如是否有遗漏的loader,或者是否开启了source map导致异步逻辑异常。
额外排查点
- 尝试给测试用例增加超时时间,排除因项目复杂导致的异步延迟:
it('should break', function(done){ this.timeout(15000); // 延长超时时间到15秒 const promise = Promise.resolve([1, 2, 3, 4 , 5]); promise.then(function(){ expect(true).to.be.false; done(); }).catch(done); });
内容的提问来源于stack exchange,提问作者Sarawut Positwinyu
相关产品推荐
相关产品推荐

