超时 - 在 jest.setTimeout 指定的 5000 毫秒超时内未调用异步回调

Posted

技术标签:

【中文标题】超时 - 在 jest.setTimeout 指定的 5000 毫秒超时内未调用异步回调【英文标题】:Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout 【发布时间】:2020-11-16 01:40:55 【问题描述】:

我正在使用 jest 和 supertest 为 API 编写测试。第一个测试按预期通过,但随后的所有测试都失败并出现以下错误:

超时 - 在 jest.setTimeout.Error 指定的 5000 毫秒超时内未调用异步回调:。 p>

我的测试套件如下所示:

const app = require('../../index.js');
const request = require('supertest');
const faker = require('faker');
const HttpStatus = require('http-status-codes');

const agent = request.agent(app);
const  truncateDatabase  = require('./helpers/truncateDatabase');

beforeEach(async (done) => 
    app.on("serverStarted", () => 
        done(); // Wait for tests to run until the server has started
    );
);

afterEach(async () => 
    await truncateDatabase();
);

describe('The register route', () => 
    it('Can run a happy flow and register a user', async (done) => 
        const firstname = faker.name.firstName();
        const lastname = faker.name.lastName();

        return agent.post('/register')
            .send( firstname, lastname )
            .expect(HttpStatus.OK)
            .then((response) => 
                expect(response.body.message).toHaveProperty('firstname', firstname);
                expect(response.body.message).toHaveProperty('lastnamename', lastname);
                done();
            );
    );

    it('Can run a second test', async () => 
        expect(true).toBe(true);
    );
);

第一个测试平均需要 500 毫秒才能完成,而第二个测试则需要 5000 多毫秒。从而抛出超时异常。

我尝试使用 async / await 更改请求调用,如下所示:

const res = await agent.post('/v1/auth/register')
    .send( firstname, lastname );

但是,这并没有解决问题。我尝试过的其他事情是:

将第三个参数传递给it 函数, 使用jest.setTimeout(10000) 增加超时, 使用 async / await 版本调用 done, 在请求结束时调用.end(), 在 jest test 命令中添加--runInBand --detectOpenHandles, 从 it 函数中删除了 describe 包装器。

以上方法似乎都没有帮助,我能做些什么来解决这个问题?更重要的是,为什么会这样?

旁注:API 使用 Sequelize 作为带有单独测试数据库的 ORM。 /register 端点没有被调用两次(我已经通过在原始代码中放置一个 console.log() 对其进行了测试)。

【问题讨论】:

【参考方案1】:

async、原始 promise 和 done 不应在测试中混合在一起,这会导致代码容易出错。承诺往往不受约束。 done 经常被不小心使用,不处理错误,如果无法访问会导致测试超时。

由于第二次测试是空操作并且不能自行超时,因此应归咎于 beforeEach。如果只有一个应用程序实例,则预计不会多次触发serverStarted。未显示serverStarted 的工作方式。

如果打算单独保留实例,则应为每个测试重新初始化:

let app, agent;

beforeEach(() => 
    jest.resetModules();
    app = require('../../index.js');
    agent = request.agent(app);
);

beforeEach((done) => 
    app.on("serverStarted", () => 
        // probably needs to handle errors
        done();
    );
);

【讨论】:

以上是关于超时 - 在 jest.setTimeout 指定的 5000 毫秒超时内未调用异步回调的主要内容,如果未能解决你的问题,请参考以下文章

超时 - 在 jest.setTimeout 指定的 5000 毫秒超时内未调用异步回调

JEST:“在 jest.setTimeout 指定的 5000 毫秒超时内未调用异步回调。”,尽管它已经配置

带有 Typescript 错误的玩笑:超时 - 在 jest.setTimeout.Timeout 指定的 5000 毫秒超时内未调用异步回调

Got Timeout - 在 jest.setTimeout 指定的 5000 毫秒超时内未调用异步回调

描述块内的 jest.setTimeOut() 是不是仅将超时应用于描述块内的测试

测试套件无法运行