使用Jest+TypeScript时传入done()参数出现类型错误
Jest异步测试问题:解决未退出提示与TypeScript类型错误
问题场景
在Node.js+TypeScript项目中使用Jest编写接口测试时遇到两个问题:
- 测试用例未使用
done参数时,执行成功后Jest提示:
Jest did not exit one second after the test run has completed.This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with
--detectOpenHandlesto troubleshoot this issue.
- 为解决上述问题尝试在测试用例或
afterAll中添加done参数后,出现TypeScript类型错误:
Argument of type '(this: TestContext, done: DoneFn_2) => Promise
' is not assignable to parameter of type 'TestFn'. Type '(this: TestContext, done: DoneFn_2) => Promise ' is not assignable to type 'PromiseReturningTestFn'.ts(2345)
错误原因
- 类型错误根源:Jest的测试函数不允许同时使用
async/await(Promise方式)和done回调。async函数本身会返回Promise,而Jest会将带done参数的测试视为回调式异步测试,两种模式冲突导致类型不匹配。 - 未退出提示根源:测试结束后仍有未关闭的异步资源(如HTTP服务器、数据库连接、请求句柄等),Jest无法正常退出。
解决方案
1. 移除done参数,使用纯async/await模式
async/await本身就是Jest支持的异步测试方式,无需手动调用done。修改后的测试用例如下:
/* 确保app(及其路由)加载完成后再测试 */ beforeAll(async () => { await app.ready() }) afterAll(async () => { await app.close() }) describe('用户可以创建新账户', () => { it('应返回状态码201表示成功', async () => { const response = await request(app.server).post('/users/create').send({ email: 'account@jest.com', password: 'weakpassword123', }) expect(response.statusCode).toBe(201) }) })
2. 排查并关闭未释放的异步资源
针对Jest未退出的问题,执行以下步骤:
- 运行
npx jest --detectOpenHandles命令,查看具体未关闭的资源句柄。 - 检查
afterAll中的app.close()是否彻底关闭了所有依赖资源:- 如果项目使用数据库连接池,需在
afterAll中额外调用连接池的关闭方法。 - 如果有其他异步服务(如WebSocket、消息队列),确保测试结束后都执行了关闭操作。
- 如果项目使用数据库连接池,需在
3. 若需使用回调式异步(不推荐)
如果必须使用done回调处理异步逻辑,不要同时使用async关键字,示例如下:
it('应返回状态码201表示成功', (done) => { request(app.server) .post('/users/create') .send({ email: 'account@jest.com', password: 'weakpassword123' }) .end((err, response) => { if (err) return done(err) expect(response.statusCode).toBe(201) done() }) })
内容的提问来源于stack exchange,提问作者Bruno Corrêa
相关产品推荐
相关产品推荐

