Ergeros
Ergeros

Reputation: 491

NestJS - Test suite failed to run Cannot find module 'src/article/article.entity' from 'comment/comment.entity.ts'

i need help with nestjs and jest testing. I am new to NestJS and i got stuck on Cannot find module error when i run tests.

I am trying to test my service and when i run tests i have received error message:

src/article/article.service.spec.ts ● Test suite failed to run

Cannot find module 'src/article/article.entity' from 'comment/comment.entity.ts'

Require stack:
  comment/comment.entity.ts
  article/article.entity.ts
  article/article.service.spec.ts

   6 |   ManyToOne,
   7 | } from 'typeorm';
>  8 | import { Article } from 'src/article/article.entity';
     | ^
   9 | 
  10 | @Entity()
  11 | export class Comment {

  at Resolver.resolveModule (../node_modules/jest-resolve/build/index.js:307:11)
  at Object.<anonymous> (comment/comment.entity.ts:8:1)

This similiar error is showing up through all other tests in different controllers, services etc.

There is my code what i am trying to test.

article.service.ts

import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Article } from "./article.entity";
import { ArticleRepository } from "./article.repository";
import { ArticleDTO } from "./dto/article.dto";
import { DeleteResult } from "typeorm";
import { ArticleRO } from "./dto/article.response";
import { UserRepository } from "src/user/user.repository";

@Injectable()
export class ArticleService {
  constructor(
    private readonly articleRepository: ArticleRepository,
    private readonly userRepository: UserRepository
  ) {}

  async getAllPosts(): Promise<ArticleRO[]> {
    return await this.articleRepository.find();
  }
}

article.repository.ts

import { Repository, EntityRepository } from 'typeorm';
import { Article } from './article.entity';
@EntityRepository(Article)
export class ArticleRepository extends Repository<Article> {
}

article.service.specs.ts

import { Test, TestingModule } from "@nestjs/testing";
import { getRepositoryToken } from "@nestjs/typeorm";
import { Article } from "./article.entity";
import { ArticleRepository } from "./article.repository";
import { ArticleService } from "./article.service";
import { ArticleRO } from "./dto/article.response";

describe("PostService", () => {
  let service: ArticleService;
  let articleRepository: ArticleRepository;
  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        ArticleService,
        {
          provide: getRepositoryToken(Article),
          useClass: ArticleRepository,
        },
      ],
    }).compile();

    service = module.get<ArticleService>(ArticleService);
    articleRepository = module.get<ArticleRepository>(
      getRepositoryToken(Article)
    );
  });

  it("should be defined", () => {
    expect(service).toBeDefined();
  });
  describe("findAll", () => {
    it("should return an array of cats", async () => {
      const result: ArticleRO[] = [];
      jest.spyOn(service, "getAllPosts").mockResolvedValueOnce(result);

      expect(await service.getAllPosts()).toBe(result);
    });
  });
});


comment.entity.ts

import {
  Entity,
  Column,
  PrimaryGeneratedColumn,
  CreateDateColumn,
  ManyToOne,
} from 'typeorm';
import { Article } from 'src/article/article.entity';

@Entity()
export class Comment {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  author: string;

  @Column()
  content: string;

  @CreateDateColumn()
  createdAt: Date;

  @ManyToOne(
    () => Article,
    article => article.comments,
  )
  article: Article;
}

there are my jest settings from package.json.

"jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".spec.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }

I tried to change my rootDir to "./src" but this does not work.

I generated project with nest new blabla. So my jest settings are default. Maybe i am doing something wrong with my custom repository mocking in tests.

Upvotes: 48

Views: 45055

Answers (5)

Mistico
Mistico

Reputation: 355

I had the same issue but was solved by adding these lines of code in /test/jest-e2e.json

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

Upvotes: 9

BIS Tech
BIS Tech

Reputation: 19504

right click on the file and click "Copy Relavant Path" and paste and remove file extension

ex:

import { function_name } from '/paste full relevant path to here and remove extenstion'

Upvotes: 0

Matthew Rideout
Matthew Rideout

Reputation: 8546

Changing To Relative Imports

And the VSCode setting to automate that.

I had to change my VSCode import settings to use relative paths for TypeScript. By default, VSCode was importing with "shortest" path, which looked like src/auth/user.entity. My NestJS app was compiling fine, but I was getting the same Jest testing errors as you.

After changing setting TypeScript › Preferences: Import Module Specifier to relative, the modules are importing like ../auth/user.entity. (Ensure you're changing the setting for TypeScript, as there is an identical setting for JavaScript. I changed both.).

Making these module import changes fixed my NestJS Jest testing issues, with similar Cannot find module 'src/article/article.entity' from 'comment/comment.entity.ts' style errors.

More details about changing the VSCode typescript preferences are here: https://stackoverflow.com/a/53137571/8177355

Upvotes: 27

Parziphal
Parziphal

Reputation: 6902

You can tell Jest how to resolve module paths by configuring the moduleNameMapper option, which is useful if you're using packages like module-alias or if you're using absolute paths. Add these lines to your Jest configuration:

{
  // ...

  "jest": {
    // ...

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

Now modules that start with src/ will be looked into <rootDir>/, which is the src folder by default (this configured a few lines above). Check out the documentation link above to get ideas of everything you can do with this.

I don't know what's wrong with using absolute paths as the other reply said, it's not only useful but it also works just fine in both NestJS and in Angular.

Upvotes: 72

dombre77
dombre77

Reputation: 527

don´t use paths like "src/article/article.entity" in your app, these are not available after compile. Instead take relative paths like "../../article/article.entity" (this is just a guessed path)...Regards

Upvotes: 47

Related Questions