typescriptjestjsnestjse2e-testingts-jest

ts-jest nestjs Cannot read properties of undefined of an enum


I'm creating an application using NestJS and using ts-jest for e2e testing. This is my code repository: https://github.com/redplane/jest-issue

I have one controller with the following logic:

@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.log(ShapeDimensions);
    await this.__joiService.validateAsync(query, processImageQueryJoiSchema);
  }
}

If I request to this api using postman, everything works fine and the console prints:

{ WIDTH: 'WIDTH', HEIGHT: 'HEIGHT' }

However, when I tried using e2e test by using this command:

npm run e2e:api

I got this error:

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)

And if I comment out: await this.__joiService.validateAsync(query, processImageQueryJoiSchema);

Value of console.log(ShapeDimensions); is undefined, however, if I print an enum of api project, it is still printed normally.

This is my 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',
};

I have tried following the solutions metioned in:

-> I checked circular dependency and found nothing

Any solution please ?

Thanks,


Solution

  • After few hours relaxing my mind, suddenly I found the solution:

    In jest.config.ts, I had this part:

    moduleNameMapper: {
        "@image-service/api": "<rootDir>/../api/src/index.ts",
        "@image-service/api-business": "<rootDir>/../../libs/api-business/src"
      },
    

    Previously when I worked with the old version of NestJS and jest, I got to use this to make my test files recognize my libraries project.

    With the current version of NestJS and jest (mostly it is about jest), after having removed this config, my test ran successfully.

    So the new jest.config.ts is:

    /* 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',
    };
    

    So the result is: enter image description here

    Hope this helps anyone who has the same frustrating issue.