如何在 Global Jest 设置中查找别名?

问题描述 投票:0回答:3

我只想在所有测试用例之前运行一些东西。因此,我创建了一个全局函数,并在 jest 配置中指定了 globalSetup 字段:

globalSetup: path.resolve(srcPath, 'TestUtils', 'globalSetup.ts'),

但是,在 globalSetup 中,我使用了一些别名 @,而 Jest 抱怨它找不到它们。

别名整理完毕后,如何运行 globalSetup

我的Jest配置如下:

module.exports = {
  rootDir: rootPath,
  coveragePathIgnorePatterns: ['/node_modules/'],
  preset: 'ts-jest',
  setupFiles: [path.resolve(__dirname, 'env.testing.ts')],
  setupFilesAfterEnv: [path.resolve(srcPath, 'TestUtils', 'testSetup.ts')],
  globalSetup: path.resolve(srcPath, 'TestUtils', 'globalSetup.ts'),
  globals: {},
  testEnvironment: 'node',
  moduleFileExtensions: ['js', 'ts', 'json'],
  moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '<rootDir>/' })
};

当我在每次测试之前运行 testSetup 时,它可以正常运行别名,但是 globalSetup 不会发生这种情况。

有什么线索我能做什么吗?

javascript typescript testing jestjs ts-jest
3个回答
5
投票

我通过在全局设置文件顶部包含

tsconfig-paths/register
成功完成了这项工作:

// myGlobalSetupFile.ts

import 'tsconfig-paths/register';
import { Thing } from './place-with-aliases';

export default async () => {
  await Thing.doGlobalSetup();
}

您必须确保您的项目中安装了

tsconfig-paths


1
投票

不幸的是,根据此问题的评论,我发现没有解决方案: https://github.com/facebook/jest/issues/6048

总结是 globalSetup 在 Jest 生态系统之外运行,因此它不会识别别名等。

有多种解决方法,例如,如果您的 npm run test 命令如下所示:

"test": "jest --config config/jest.config.js --detectOpenHandles --forceExit"

然后你可以这样做:

"test": "node whateverBeforeJest.js && jest --config config/jest.config.js --detectOpenHandles --forceExit"

0
投票

Javier 是对的,globalSetup 在 Jest 生态系统之外运行,并且不会识别别名。

但是我这样解决了问题:

文件夹结构:

src
└── __tests__
    └── client 
    └── server
        └── tsconfig.json
        └── _config
            └── jest.config.ts
            └── jest.global.setup.ts
            └── jest.global.teardown.ts
        └── controllers
            └── public.test.ts
            └── ...more
└── client
    └── ...more
└── server
    └── controllers
    └── ...more
└── tsconfig-base.json
package.json

package.json

{
    ...
    "dependencies": {
        ...
    },
    "devDependencies": {
        "supertest": "^6.3.4",
        "ts-jest": "^29.1.2",
        "tsconfig-paths": "^4.2.0",
        "typescript": "^5.4.2",
        ...
    },
    "_moduleAliases": {
        "@/controllers": "bin/controllers",
        "@/enums": "bin/enums",
        "@/exceptions": "bin/exceptions",
        "@/interfaces": "bin/interfaces"
    },
    ...
}

tsconfig-base.json

{
    "compilerOptions": {
        "target": "es2020",
        "types": ["node", "jest"],
        "composite": true,
        "noImplicitReturns": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "sourceMap": true,
        "strict": true,
        "alwaysStrict": true,
        "noImplicitAny": true,
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "skipLibCheck": true,
        "resolveJsonModule": true,
        "esModuleInterop": true,
        "removeComments": true,
        //"traceResolution": true,
    },
    "include": [
    ],
    "exclude": [
        "**/node_modules/*",
        "bin",
        "public"
    ]
}
{
    "extends": "../../tsconfig-base.json",
    "compilerOptions": {
        "module": "NodeNext",
        "baseUrl": ".",
        "rootDir": "../..",
        "outDir": "../../../bintests",

        "paths": {
            "@/controllers/*": ["../../server/controllers/*"],
            "@/enums/*": ["../../server/enums/*"],
            "@/exceptions/*": ["../../server/exceptions/*"],
            "@/interfaces/*": ["../../server/interfaces/*"]
        },
    },
    "include": [
        "**/next-env.d.ts",
        "**/*.ts",
        "../../server/**/*.ts"
    ],
    "exclude": [
        "**/node_modules/*",
        "bin",
        "public"
    ]
}

jest.config.ts

import _path from 'path';
import type { Config } from '@jest/types';
import { pathsToModuleNameMapper } from 'ts-jest';

const testsSrc: string = _path.resolve(__dirname, '../..');
const serverSrc: string = _path.resolve(__dirname, '../../../server');

export const aliases: any = {
    '@/controllers/*': [`${serverSrc}/controllers/*`],
    '@/enums/*': [`${serverSrc}/enums/*`],
    '@/exceptions/*': [`${serverSrc}/exceptions/*`],
    '@/interfaces/*': [`${serverSrc}/interfaces/*`],
};

const config: Config.InitialOptions = {
    rootDir: `${testsSrc}/server`,
    roots: ['<rootDir>'],
    testMatch: [
        //'**/__tests__/**/*.+(ts|tsx|js)',
        '**/?(*.)+(spec|test).+(ts|tsx|js)',
    ],
    transform: {
        '^.+\\.(ts|tsx)$': 'ts-jest',
    },

    preset: 'ts-jest',
    //'ts-jest/presets/default-esm',
    testEnvironment: 'node',
    verbose: true,
    automock: false,
    globalSetup: '<rootDir>/_config/jest.global.setup.ts',
    globalTeardown: '<rootDir>/_config/jest.global.teardown.ts',

    modulePaths: [serverSrc], // <-- This will be set to 'baseUrl' value
    moduleNameMapper: pathsToModuleNameMapper(aliases /* ,{ prefix: '<rootDir>/' } */),
};

export default config;

jest.global.setup.ts

import _path from 'path';
import * as TSConfigPaths from 'tsconfig-paths';
import { aliases } from './jest.config';

const baseUrl: string = _path.resolve(__dirname, '..');
// @ts-ignore: TS6133
const cleanup: () => void = TSConfigPaths.register({
    baseUrl,
    paths: aliases, // tsConfig.compilerOptions.paths,
});

import ExpressApp from '@/controllers/express-server';
import PublicController from '@/controllers/public';

export const globalSetup: () => Promise<void>
    = async (): Promise<void> => {

        const expressApp: ExpressApp | null = new ExpressApp();
        expressApp?.initializeControllers([
            new PublicController(expressApp),
        ]);

        (globalThis as any).__ExpressApp__ = expressApp;

    };

// afterAll(async (): Promise<void> => {
// });

export default globalSetup;

最后,public.test.ts

import request from 'supertest';
import express from 'express';
import { StatusCodes } from 'http-status-codes';

import ExpressApp from '@/controllers/express-server';

describe('public.test.ts', () => {

    //let agent: request.Agent;
    //let tmp: any = null;

    beforeAll(async (): Promise<void> => {
        ExpressApp.me = (globalThis as any).__ExpressApp__;
        //agent = request.agent(ExpressApp.me?.app || undefined);
    });

    test('get /public/v1/version', async (): Promise<void> => {
        const expressApp: ExpressApp | null = ExpressApp.me;
        const response: any = await request(expressApp?.app as express.Application)
            .get('/public/v1/version');
        expect(response.statusCode).toBe(StatusCodes.OK);
        expect(response.body).toBe('1.0.0.0');
    });

});

© www.soinside.com 2019 - 2024. All rights reserved.