Я создаю приложение, используя NestJS и ts-jest для тестирования e2e.
Это мой репозиторий кода:
https://github.com/redplane/jest-issue
У меня есть один контроллер со следующей логикой:
@Controller({
path: 'api/shape',
scope: Scope.REQUEST,
})
export class ShapeController {
public constructor(
@Inject(AppInjectors.SERVICE__JOI)
private readonly __joiService: IJoiService
) {}
@Get()
public async processAsync(@Query() query: ProcessShapeQuery): Promise<void> {
// Do the parameter validation
console.info(ShapeDimensions);
await this.__joiService.validateAsync(query, processImageQueryJoiSchema);
}
}
Если я запрошу этот API с помощью почтальона, все будет работать нормально, и консоль выведет:
{ WIDTH: 'WIDTH', HEIGHT: 'HEIGHT' }
Однако когда я попытался использовать тест e2e с помощью этой команды:
npm run e2e:api
Я получил эту ошибку:
TypeError: Cannot read properties of undefined (reading 'PIXEL')
5 | export const imageFrameOptionsJoiSchema = Joi.object<ShapeFrameOptions>({
6 | size: Joi.number().min(1),
> 7 | unit: Joi.any().valid(ShapeUnits.PIXEL),
| ^
8 | dimension: Joi.any().valid(ShapeDimensions.HEIGHT, ShapeDimensions.WIDTH)
9 | });
10 |
at Object.<anonymous> (../api/src/app/validators/image-frame-options.joi-schema.ts:7:36)
at Object.<anonymous> (../api/src/app/validators/process-image-options.joi-schema.ts:3:1)
at Object.<anonymous> (../api/src/app/validators/process-image-query.joi-schema.ts:2:1)
at Object.<anonymous> (../api/src/app/modules/apis/shape/shape.controller.ts:3:1)
at Object.<anonymous> (../api/src/app/modules/apis/shape/shape.module.ts:2:1)
at Object.<anonymous> (../api/src/app/modules/apis/shape/index.ts:1:1)
at Object.<anonymous> (../api/src/app/modules/apis/index.ts:1:1)
at Object.<anonymous> (../api/src/app/modules/index.ts:1:1)
at Object.<anonymous> (../api/src/app/index.ts:5:1)
at Object.<anonymous> (../api/src/index.ts:1:1)
at Object.<anonymous> (src/modules/test-app.module.ts:2:1)
at Object.<anonymous> (src/api/image/api-e2e.spec.ts:5:1)
А если я закомментирую:
await this.__joiService.validateAsync(query, processImageQueryJoiSchema);
Значение console.info(ShapeDimensions); не определено, однако, если я распечатаю перечисление проекта api, оно все равно будет печататься нормально.
Это мой jest.config.ts:
/* eslint-disable */
export default {
displayName: 'api-e2e',
preset: '../../jest.preset.js',
globalSetup: '<rootDir>/src/support/global-setup.ts',
globalTeardown: '<rootDir>/src/support/global-teardown.ts',
setupFiles: ['<rootDir>/src/support/test-setup.ts'],
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': [
'ts-jest',
{
tsconfig: '<rootDir>/tsconfig.spec.json',
},
],
},
moduleNameMapper: {
"@image-service/api": "<rootDir>/../api/src/index.ts",
"@image-service/api-business": "<rootDir>/../../libs/api-business/src"
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/api-e2e',
};
Я пробовал следовать решениям, указанным в:
Ошибка выполнения машинописного текста: невозможно прочитать свойство неопределенного (перечисления)
-> Я проверил циклическую зависимость и ничего не нашел
Любое решение, пожалуйста?
Спасибо,






После нескольких часов расслабления ума я внезапно нашел решение:
В jest.config.ts у меня была такая часть:
moduleNameMapper: {
"@image-service/api": "<rootDir>/../api/src/index.ts",
"@image-service/api-business": "<rootDir>/../../libs/api-business/src"
},
Раньше, когда я работал со старой версией NestJS и jest, мне приходилось использовать это, чтобы мои тестовые файлы распознавали проект моей библиотеки.
С текущей версией NestJS и jest (в основном речь идет о jest), после удаления этой конфигурации мой тест прошел успешно.
Итак, новый jest.config.ts:
/* eslint-disable */
export default {
displayName: 'api-e2e',
preset: '../../jest.preset.js',
globalSetup: '<rootDir>/src/support/global-setup.ts',
globalTeardown: '<rootDir>/src/support/global-teardown.ts',
setupFiles: ['<rootDir>/src/support/test-setup.ts'],
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': [
'ts-jest',
{
tsconfig: '<rootDir>/tsconfig.spec.json',
},
],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/api-e2e',
};
Итак, результат:
Надеюсь, это поможет любому, у кого такая же неприятная проблема.