在测试完成之前运行 Jest 全局拆卸?

Sim*_*leJ 9 javascript node.js jestjs

我试图确保在我的所有 Jest 测试运行后我的应用程序被正确销毁,但我在尝试使用 Jest 的全局拆卸配置值时遇到了一些非常奇怪的行为。

情况如下:我的应用程序创建了一个数据库连接。它还有一个destroy关闭数据库连接的方法。这有效。

我有一个启动服务器的测试,运行对数据库连接的查询。在我的全局拆卸函数中,我调用了app.destroy(),但进程挂起。

如果我注释掉destroy全局拆卸函数中的调用并app.destroy()在查询后放入我的测试中,Jest 不会像预期的那样挂起和关闭。我也可以放入afterAll(() => app.destroy())我的测试文件并且一切正常。

这是我的 jest.config.js

module.exports = {
  testEnvironment: 'node',
  roots: [
    '<rootDir>/src'
  ],
  transform: {
    '^.+\\.tsx?$': 'ts-jest'
  },
  testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$',
  moduleFileExtensions: [
    'ts',
    'tsx',
    'js',
    'jsx',
    'json',
    'node'
  ],
  globalSetup: '<rootDir>/src/testSetup.ts',
  globalTeardown: '<rootDir>/src/testTeardown.ts'
};
Run Code Online (Sandbox Code Playgroud)

这是测试(它目前是应用程序中唯一的测试):

import app from '../..';

describe('User router', () => {
  it('Should respond with an array of user objects', async () => {
    await app.models.User.query();
  });
});
Run Code Online (Sandbox Code Playgroud)

这是全球拆解<rootDir>/src/testTeardown.ts

import app from './index';

module.exports = async function testTeardown() {
  await app.destroy();
};
Run Code Online (Sandbox Code Playgroud)

使用上面的代码,测试完成后进程挂起。我试过添加一个console.logtotestTeardown和测试结束,并且日志以正确的顺序发生:测试日志,然后是拆卸日志。但是,如果我app.destroy()进入我的测试,它可以完美运行:

import app from '../..';

describe('User router', () => {
  it('Should respond with an array of user objects', async () => {
    await app.models.User.query();
    await app.destroy();
  });
});
Run Code Online (Sandbox Code Playgroud)

这也有效:

import app from '../..';

afterAll(() => app.destroy());

describe('User router', () => {
  it('Should respond with an array of user objects', async () => {
    await app.models.User.query();
  });
});
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

也只是为了胡闹和傻笑,我尝试global._app在测试中设置 a然后在拆卸处理程序中检查它,但它是undefined. Jest 的设置/拆卸功能甚至在与测试相同的过程中运行吗?

For*_*say 11

不,jest globalSetup 和 globalTeardown 文件不一定与您的测试在同一进程中运行。这是因为 jest 并行化您的测试并在单独的进程中运行每个测试文件,但对于组合的一组测试文件只有一个全局设置/拆卸阶段。

您可以使用setupFiles添加一个文件,该文件与每个测试文件一起运行。在setupFiles文件中,您可以放置​​:

afterAll(() => app.destroy());
Run Code Online (Sandbox Code Playgroud)

你的笑话配置只是

module.exports = {
  testEnvironment: 'node',
  roots: [
    '<rootDir>/src'
  ],
  transform: {
    '^.+\\.tsx?$': 'ts-jest'
  },
  testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$',
  moduleFileExtensions: [
    'ts',
    'tsx',
    'js',
    'jsx',
    'json',
    'node'
  ],
  setupFiles: ['<rootDir>/src/testSetup.ts']
};
Run Code Online (Sandbox Code Playgroud)

  • PS 您可以在调用 jest 时通过 `--runInBand` 来强制您的测试在与全局设置/拆卸相同的过程中运行,但我认为 jest 仍然会为每个有点孤立的测试创建一个“模拟”环境。 (3认同)
  • 我认为 `afterAll` 在 `setupFiles` 中不可用。它可能应该是“setupFilesAfterEnv”。 (3认同)