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,
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',
};
Hope this helps anyone who has the same frustrating issue.