2
votes

I created a simple REST API using Mongdoose with Nestjs. I have in total 2 tests and they are failing. The test output:

FAIL src/app/auth/auth.service.spec.ts ● Test suite failed to run

Cannot find module '@shared/errors' from 'auth.service.ts'

   5 | 
   6 | import { AppLogger } from '../logger/logger';
>  7 | import { Errors } from '@shared/errors';
     | ^
   8 | import { ILoginDto } from './dto/login.dto';
   9 | import { ITokenDto } from './dto/auth.dto';
  10 | import { IUser } from '@user/document/user.doc';

  at Resolver.resolveModule (../../node_modules/jest-resolve/build/index.js:259:17)
  at Object.<anonymous> (auth/auth.service.ts:7:1)

FAIL src/app/user/user.service.spec.ts ● Test suite failed to run

Cannot find module '@shared/errors' from 'user.service.ts'

  1 | import { BadRequestException, Injectable } from '@nestjs/common';
  2 | import { InjectModel } from '@nestjs/mongoose';
> 3 | import { Errors } from '@shared/errors';
    | ^
  4 | import { createMultipleRandom } from '@shared/utils';
  5 | import { Model } from 'mongoose';
  6 | import { AppLogger } from '../logger/logger';

  at Resolver.resolveModule (../../node_modules/jest-resolve/build/index.js:259:17)
  at Object.<anonymous> (user/user.service.ts:3:1)

Test Suites: 2 failed, 2 total Tests: 0 total Snapshots: 0 total Time: 2.751s Ran all test suites.

tsconfig.json:

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "paths": {
      "@app/*": ["src/app/*"],
      "@auth/*": ["src/app/auth/*"],
      "@config/*": ["config/*"],
      "@logger/*": ["src/app/logger/*"],
      "@shared/*": ["src/app/shared/*"],
      "@user/*": ["src/app/user/*"],
    }
  },
  "include": [
    "src/**/*"
  ],

  "exclude": ["node_modules", "dist"]
}

auth.service.spec.ts:

import { Test, TestingModule } from '@nestjs/testing';
import { AuthService } from './auth.service';
describe('AuthService', () => {
  let service: AuthService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [AuthService],
    }).compile();

    service = module.get<AuthService>(AuthService);
  });

  it('should be defined', () => {
    expect(service).toBeDefined();
  });
});

In @shared/errors.ts I just export a constant variable. Since it is not a module, how should I import this in a test ? How can I solve this problem ?

2

2 Answers

2
votes

As you are using typescript's path mapping, you need to also update your jest config with the mapped paths as well. Your jest config needs to have the following added:

{
  ...
  "moduleNameMapper": {
    "^@Shared/(.)*$": "<rootDir>/src/app/shared/$1"
  }
}

Assuming that your <rootDir> is set to be . and not ./src. You can find more info on it here.

0
votes

Here is a detailed configurations for jest-path-resolving problem.

The defined keys inside the moduleNameMapper will be replaced with their values.

For example, when jest sees '@resources', it will replace it with 'src/resources'

(Using index file helps a lot)

Jest configuration in the package.json

 "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "moduleNameMapper": {
      "@resources": "<rootDir>/resources",
      "@shared": "<rootDir>/shared",
      "@email": "<rootDir>/email",
      "@auth": "<rootDir>/auth",
      "@config": "<rootDir>/config",
      "@database": "<rootDir>/database"
    },
    "testRegex": ".*\\.spec\\.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "collectCoverageFrom": [
      "**/*.(t|j)s"
    ],
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }

Typescript configuration

 "paths": {
      "@resources/*": ["src/resources/*"],
      "@resources": ["src/resources"],
      "@shared/*": ["src/shared/*"],
      "@shared": ["src/shared"],
      "@email/*": ["src/email/*"],
      "@email": ["src/email"]
    }