supertest提示jest.setTimeout(2000) 修改超时后仍超时如何解决
supertest 结合 Jest 接口测试持续超时解决方案
你的超时问题根本不是超时阈值设置不够,是代码里的异步写法错误、拼写错误、资源未释放导致Jest判定异步逻辑始终未执行完成,具体问题和修复方式如下:
1. 异步写法严重冲突
Jest的异步钩子(beforeAll/afterAll/it)只支持三种异步写法,绝对不能混用,混用就会出现逻辑执行完但Jest一直等待、直到触发超时的问题:
- 写法1:回调形式,传入
done参数,所有逻辑执行完手动调用done()告知Jest用例结束 - 写法2:返回Promise形式,Jest会等Promise状态变更后再结束用例
- 写法3:
async/await形式,本质是写法2的语法糖,Jest会等async函数执行完再结束
你的代码里同时给async函数加了done参数,但是全程没有调用done(),Jest会一直等待done()被调用,永远不会结束当前用例/钩子。
修复方式: - 删掉
beforeAll(async (done) => {里的done参数,保留async即可 - 删掉
afterAll(async (done) => {里的done参数,保留async即可 - 删掉
describe("User Module", (done) => {里的done参数,describe回调根本不需要done参数 - 所有
it块如果用了return request(...)的Promise写法,就删掉it回调里的done参数,不要给.expect()传done回调,直接返回promise链即可
2. 低级拼写错误导致用例挂死
你第二个测试用例里写的是.expect(400, doe),把done拼成了不存在的变量doe,运行到这里会触发未定义错误,同时因为异步写法混乱,这个错误不会被Jest正常捕获,直接导致用例挂死。
3. 数据库连接未手动关闭
你的afterAll钩子只执行了删库操作,没有主动关闭Mongoose连接,测试执行完后依然有未释放的数据库连接句柄,Jest会判定存在未完成的异步操作,在--watchAll模式下这个问题会更明显。
修复方式:在afterAll里加连接关闭逻辑:
afterAll(async () => { await conn.connection.db.dropDatabase(); await mongoose.connection.close(); // 新增这行 });
4. 测试用例重名易引发watch模式异常
你4个创建用户的测试用例完全重名,都叫POST -> Create User,Jest在watch模式下追踪用例状态、增量执行时容易出现匹配异常,建议给每个用例加场景后缀,比如:
POST -> Create User (invalid email format)POST -> Create User (password too short)POST -> Create User (invalid airline value)POST -> Create User (valid params)
额外配置建议
超时时间不需要设置到100000ms这么夸张,接口测试30000ms(30秒)完全足够,直接在测试文件最顶部加一行配置即可:
jest.setTimeout(30000);
如果还是偶发连不上本地MongoDB的问题,先检查有没有之前跑测试挂死的Node进程残留,残留进程会占用Mongo连接,导致新启动的测试连库超时。
内容的提问来源于stack exchange,提问作者Sathak Hussam
相关产品推荐
相关产品推荐

