Jest 在使用 Express 完成测试运行后一秒钟没有退出



我正在使用JEST对我的快速路由进行单元测试。

在运行yarn test时,我所有的测试用例都通过了,但是我遇到了错误

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 `--detectOpenHandles` to troubleshoot this issue.

我使用了async&done,但它仍然抛出上述错误。

下面是我的规格代码。请帮忙

routes.spec.ts

const request = require('supertest');
describe('Test the root path', () => {
  const app = require('./index');
  test('GET /gql/gql-communication-portal/release-notes', async (done) => {
    const response = await request(app).get('/gql/gql-communication-portal/release-notes');
    expect(response.status).toBe(200);
    done();
  });
});

我的问题已通过以下代码解决:

beforeAll(done => {
  done()
})
afterAll(done => {
  // Closing the DB connection allows Jest to exit successfully.
  mongoose.connection.close()
  done()
})

我已将此行添加到package.json

它对我有用

jest --runInBand --detectOpenHandles --forceExit

对我来说,这是一个不同的问题,我使用 supertest 来测试路由本身,所以我不得不关闭与服务器本身的连接。

afterAll(done => {
    server.close();
    done();
});

您可以在之前启动服务器全部阻止并关闭:

beforeAll(() => {
   server = app.listen(someRandomNumberHere); // Random number is needed to avoid using same port in different tests if you run in parallel
})
afterAll(() => {
   server.close()
})

如果您不是这种情况,则此问题可能对您有用

就我而言,我只是将app.listen()与我的应用程序分开。因此,使用 Express 时,您的应用将以导出完成。

// index.js
module.exports = app;

只需创建另一个文件即可侦听端口。

// server.js
const app = require('./index')
app.listen(...)

如果您在测试中仅导入索引(应用程序index.js),则它应该无需额外配置即可工作。当然,您需要调整快速应用程序的启动。它现在应该使用server.js.

我遇到了同样的问题,但是在我的package.json文件中,我添加了"test": "jest --detectOpenHandles"并运行了npm test --detectOpenHandles。这次我没有收到错误消息。也许你可以尝试这样做。

添加

jest.useFakeTimers();

在测试套件开始时为我修复了它。

可能来自渲染组件部分中定义的计时器(如受限制的按钮、模拟等)。

这对

我有用

const mongoose = require('mongoose');
    afterAll(async(done) => {
  // Closing the DB connection allows Jest to exit successfully.
  try {
    await mongoose.connection.close();
    done()
  } catch (error) {
    console.log(error);
    done()
  }
  // done()
})

对于 Firebase,我必须调用 cleanup()

import {
    assertFails,
    assertSucceeds,
    initializeTestEnvironment,
    RulesTestEnvironment,
} from "@firebase/rules-unit-testing";
import { doc, setDoc } from "firebase/firestore";
it('creates a new user document in firebase', async () => {
    const testEnv = await initializeTestEnvironment({
        projectId: "appname-test",
        firestore: {
            host: 'localhost',
            port: 8088
        }
    });
    const alice = testEnv.authenticatedContext("alice");
    await assertSucceeds(setDoc(doc(alice.firestore(), "users", "alice"), {
        fname: "Alice",
        lname: "Wonderland",
        dob: "18/01/1999",
        email: "alice@example.com"
    }));
    return await testEnv.cleanup();
});

你可以试试这个

"测试":"开玩笑 --运行带 --强制退出"

我遇到了同样的问题,但是,我正在将pg模块与我的NodeJS Express应用程序一起使用。如果对他们有帮助,我也想为那些使用此堆栈的人发布此内容。

从本质上讲,supertest创建一个服务器连接,有些人可能会收到TCPSERVERWRAP错误,因为它没有关闭,无论我使用async/await还是开玩笑done回调。因此,必须在每次测试后将其关闭。最重要的是,数据库连接保持打开状态,所以我嘲笑它。

关闭服务器连接并一起模拟pg为我解决了错误。

products.tests.ts

import request from 'supertest'
import { Pool } from 'pg'
import app from '../app'
import type { Server } from 'http'
jest.mock('pg')
const { ROUTE_VERSION = '/v1' } = process.env
const route = (path: string) => [ROUTE_VERSION, path].join('')
const pool = new Pool()
let server: Server
beforeEach(() => {
   server = app.listen(4000)
})
afterEach(() => {
   server.close()
})
describe('GET /products', () => {
   it('returns array of products', async () => {
      await request(server)
         .get(route('/products'))
         .expect(200)
         .expect((res) => {
            expect(pool.query).toBeCalledTimes(1)
            expect(res.body).toBeInstanceOf(Array)
            expect(res.body).not.toHaveLength(0)
         })
   })
})

更新:旨在使用beforeEachafterEach在每次测试后关闭服务器,否则,它仍然像以前一样保持打开状态。

更新 2:使用 async/await 否则,它将始终通过,因为request是异步的,除非您等待它完成,否则不会完成。

由于

在所有测试用例运行后没有关闭数据库连接,我遇到了同样的问题。可以使用jest.config来完成.js并将一个新文件添加到根文件夹,该文件将在所有测试用例之后全局关闭数据库连接。

在 jest.config 中.js文件将以下内容添加到模块中。

module.exports = {
   setupFilesAfterEnv: ['<rootDir>/src/runAfterAllTests.ts'],
}

然后将 runAfterAllTests.ts 添加到 src 文件夹。

runAfterAllTests.ts 将全局关闭数据库连接。对于mongodb来说,它应该是这样的。

import { client } from './database/connect';
global.afterAll(async () => {
  await client.close();
});

这将在所有测试后关闭数据库连接并解决问题。

在 NestJs 应用程序中,您有类似的东西

app = moduleFixture.createNestApplication();
await app.init();

只需将其添加到测试文件中即可

afterAll(done => {
    app.close()
    done()
})

您也可以使用异步

afterAll(async() => {
    await app.close()
})

我的问题是我使用 Sequilize ORM,但我忘记在 afterAll 函数回调内的测试结束时关闭它。

这是我的代码:

afterAll((done) => {
    MatrixTableHeaderCol.destroy({
        where: {},
        force: true
    }).then(() => {
        done();
    });
});

最新更新