npm install -D jest @types/jest ts-jest supertest @types/supertest
If you haven’t:
npm install -D @nestjs/testing
src/users/users.service.tsusers.controller.tstest/app.e2e-spec.tsjest.config.ts
Create jest.config.ts:
import type { Config } from 'jest';const config: Config = {moduleFileExtensions: ['js', 'json', 'ts'],rootDir: '.',testRegex: '.*\\.spec\\.ts$',transform: {'^.+\\.(t|j)s$': 'ts-jest',},collectCoverageFrom: ['src/**/*.(t|j)s'],coverageDirectory: './coverage',testEnvironment: 'node',};export default config;
{"scripts": {"test": "jest","test:watch": "jest --watch","test:cov": "jest --coverage","test:e2e": "jest --config ./test/jest-e2e.json"}}
export class UsersService {findAll() {return [{ id: 1, name: 'Daniel' }];}}
import { UsersService } from './users.service';describe('UsersService', () => {let service: UsersService;beforeEach(() => {service = new UsersService();});it('should return users', () => {const result = service.findAll();expect(result).toEqual([{ id: 1, name: 'Daniel' }]);});});
import { Test, TestingModule } from '@nestjs/testing';import { UsersController } from './users.controller';import { UsersService } from './users.service';describe('UsersController', () => {let controller: UsersController;const mockUsersService = {findAll: jest.fn(() => [{ id: 1, name: 'Daniel' }]),};beforeEach(async () => {const module: TestingModule = await Test.createTestingModule({controllers: [UsersController],providers: [{provide: UsersService,useValue: mockUsersService,},],}).compile();controller = module.get<UsersController>(UsersController);});it('should return users', () => {expect(controller.findAll()).toEqual([{ id: 1, name: 'Daniel' },]);});});
👉 Key idea: mock service → isolate controller
{"moduleFileExtensions": ["js", "json", "ts"],"rootDir": "../","testRegex": ".e2e-spec.ts$","transform": {"^.+\\.(t|j)s$": "ts-jest"},"testEnvironment": "node"}
import { Test } from '@nestjs/testing';import { INestApplication } from '@nestjs/common';import * as request from 'supertest';import { AppModule } from '../src/app.module';describe('App (e2e)', () => {let app: INestApplication;beforeAll(async () => {const moduleRef = await Test.createTestingModule({imports: [AppModule],}).compile();app = moduleRef.createNestApplication();await app.init();});it('/GET users', () => {return request(app.getHttpServer()).get('/users').expect(200);});afterAll(async () => {await app.close();});});
.env.testcoverageThreshold: {global: {branches: 80,functions: 80,lines: 80,statements: 80,},}
users/users.service.tsusers.service.spec.tsusers.controller.tsusers.controller.spec.ts
Think like this:
If you want next step, I can: