我正在尝试使用 Jest 为我的 Express 服务器编写集成测试。由于 Jest 并行运行测试(并且我想避免使用 --runInBand
依次运行测试),我正在使用 get-port用于查找随机可用端口的库,以便不同的测试套件不会发生端口冲突。
我的测试都成功运行,唯一的问题是服务器无法在 afterAll
Hook 内正常关闭。这会导致 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 `--detectOpenHandles` to troubleshoot this issue.
当我使用 --detectOpenHandles
标志时,Jest 只是在测试完成后挂起。控制台不会打印任何内容。
这是我的测试代码...
let axios = require('axios')
const getPort = require('get-port')
const { app } = require('../../index')
const { Todo } = require('../../models')
// set reference to server to access
// from within afterAll hook
let server
beforeAll(async () => {
const port = await getPort()
axios = axios.create({ baseURL: `http://localhost:${port}` })
server = app.listen(port)
})
afterAll(() => {
server.close()
})
describe('GET /todos', () => {
it('returns a list of todos', async () => {
const { data: todos } = await axios.get('/todos')
todos.forEach(todo => {
expect(Todo.validate(todo)).toEqual(true)
})
})
})
最佳答案
我在这个问题的 github 线程上。这正是适合我的配置。在 package.json 中
"test": "jest --no-cache --detectOpenHandles --runInBand --forceExit",
这是测试文件中的配置
afterEach(async () => {
await server.close();
});
afterAll(async () => {
await new Promise(resolve => setTimeout(() => resolve(), 10000)); // avoid jest open handle error
});
beforeEach(() => {
// eslint-disable-next-line global-require
server = require('../index');
jest.setTimeout(30000);
});
或者您只有 afterAll 为测试主体中的每个测试单独设置超时和 settimeout。这是下面的示例
afterEach(async () => {
await server.close();
});
afterAll(async () => {
await new Promise(resolve => setTimeout(() => resolve(), 10000)); // avoid jest open handle error
});
beforeEach(() => {
// eslint-disable-next-line global-require
server = require('../index');
});
describe('POST /customers', () => {
jest.setTimeout(30000);
test('It creates a customer', async () => {
const r = Math.random()
.toString(36)
.substring(7);
const response = await request(server)
.post('/customers')
.query({
name: r,
email: `${r}@${r}.com`,
password: 'beautiful',
});
// console.log(response.body);
expect(response.body).toHaveProperty('customer');
expect(response.body).toHaveProperty('accessToken');
expect(response.statusCode).toBe(200);
});
});
关于node.js - 如何在 Jest afterAll 钩子(Hook)中关闭 Express 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59011575/