【问题标题】:Jest global teardown runs before tests finish?Jest 全球拆解在测试完成之前运行?
【发布时间】:2019-06-26 12:59:23
【问题描述】:

我正在尝试确保在我的所有 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'
};

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

import app from '../..';

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

这是&lt;rootDir&gt;/src/testTeardown.ts中的全局拆解:

import app from './index';

module.exports = async function testTeardown() {
  await app.destroy();
};

使用上面的代码,测试完成后进程挂起。我尝试将console.log 添加到testTeardown 并结束测试,并且日志以正确的顺序发生:测试日志,然后是拆卸日志。但是,如果我将 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();
  });
});

这也有效:

import app from '../..';

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

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

为什么会这样?

我也尝试在测试中设置global._app,然后在拆卸处理程序中检查它,但它是undefined。 Jest 的 setup/teardown 函数是否与测试在同一进程中运行?

【问题讨论】:

    标签: javascript node.js jestjs


    【解决方案1】:

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

    您可以使用setupFiles 添加一个文件,该文件在每个测试文件的进程中运行。在setupFiles 文件中你可以放:

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

    你开玩笑的配置只是

    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']
    };
    

    【讨论】:

    • P.S.当您调用 jest 以强制您的测试在与全局设置/拆卸相同的过程中运行时,您可以传递 --runInBand,但我认为 jest 仍然会为每个有点孤立的测试创建一个“模拟”环境。
    • 感谢您的解释。 setupFiles 非常适合我的需要。
    • 我不认为afterAllsetupFiles 中可用。应该是setupFilesAfterEnv
    猜你喜欢
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    • 2016-08-07
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 2018-12-08
    相关资源
    最近更新 更多